DevIdiot!
What the fsType field in a font means, and how to read it with fontTools
Font tooling keeps mentioning fsType, and it is easy to treat it as a magic number where 0 is fine and anything else is a problem. The spec says something more specific, and a few things in it are easy to misread. So I read the field on fonts installed on my Mac, then on the fonts inside a PDF, and wrote down what each reading means. fsType is one 16-bit number with three jobsfsType lives in the OS/2 table of a TrueType or OpenType font. The OpenType spec (the OS/2 page on learn.microsoft.c
Three things I saw when a PDF had fonts I may not embed
Putting a PDF brochure on a website is a common small-site job, and converting it to a web page is the easy part. The fonts are harder to reason about. If the PDF carries a font whose license says no embedding, what does the converter do with it? I tried a set of test files to find out, and the answer was not one thing but three. What the license flag saysA font with an OS/2 table carries a 16-bit license field there, called fsType. The spec page for that table on learn.microsoft.com, which
Why my converted PDF page showed a different font: it was Type 1, not a license flag
I converted a 4-page brochure PDF to HTML and the headline font survived while the body text came out in something else. Same page, same words, different typeface. A font license flag such as fsType is one possible explanation, but in this file it was not the cause, and the real one was easy to check. What I convertedThe sample is a public brochure from the Wikimedia Commons file "Evaluating Wikipedia" (Wiki Education Foundation and others, CC BY-SA 3.0). I cut the first 4 pages out of the
Chromium turned my CFF OpenType font into Type 3 at every fsType value I tried
Which fonts survive "print to PDF" as real fonts, and which ones turn into drawing instructions? That decides what a PDF-to-HTML converter can later hand back to a browser as a web font. The fsType flag in the font's OS/2 table is the obvious suspect. In the one test below, it explained two of three fonts and nothing for the third. Three fonts, six fsType values eachThe test is small. I took Pacifico and Liberation Sans (both TrueType outlines) and Noto Serif SC (CFF outlines in an .otf), a
A font-license checkpoint for PDF-to-HTML: what fsType can and can't tell you
If you convert PDFs into web pages, someone eventually asks whether you are allowed to put the PDF's fonts into the HTML. The obvious design is a checkpoint that reads the font's license flag and stops the pipeline when it says no. Looking at what actually arrives at that point changed where I would put the check.The flag is fsType, a 16-bit field in the font's OS/2 table. Per the OpenType spec (the OS/2 page on learn.microsoft.com, read on 2026-10-28), bits 0–3 hold the usage permission, with v
What WebAssembly Changes About Browser-Local Image Compression
A browser can run a mature image encoder without sending the image to a server. WebAssembly makes that practical by letting developers compile existing native libraries for the browser. The interesting engineering decisions come afterward: how bytes reach the encoder, which thread does the work, and how much memory remains available. What runs, and whereWebAssembly, usually shortened to Wasm, is a portable binary compilation target. Languages including C, C++, and Rust can produce modules t
I built a free, privacy-first 8th Pay Commission pension calculator as a static site
India's 8th Central Pay Commission will revise pensions for roughly 69 lakh central government pensioners. Most "calculators" online are ad-heavy, English-only, or don't show their formulas. So I built one that runs entirely in the browser.Live: https://8cpc-pension-calculator.vercel.app/ (Hindi: https://8cpc-pension-calculator.vercel.app/hi/) What it doesNew basic pension at every projected fitment factor (1.92 to 3.833)DA/DR with arrears, family pension, commutation and 15-year restoratio
JSON Patch explained: how to apply one in JavaScript and Python
A PUT sends the whole document, and if someone changed a field while you were looking, your copy can overwrite it. A JSON Patch (RFC 6902) sends only the difference, as data a reviewer can read line by line. Below is one patch that uses all six operations, applied in JavaScript and Python. After that come how to generate and send one, and what each library leaves behind when a patch fails halfway. One patch can use all six operationsA patch is a JSON array of operation objects. Each has an
I solved my problem of keep forgetting my projects and work to do.
I have a really bad memory when it comes to my old projects and work to do. I couldn't find a way to manage all of them . Ofc I could pay notion or other app 12$ a month but ofc that wouldn't be fun. So I made this webapp to manage all my project , worktodo , emails to reply and etc etc, I also added a note init so if I forget something it remind me . I added a webhook connected to my WhatsApp so it send me a notification on wp . And I need a honest suggestion should I add am ai to manage all th
The quiet engineering of instant play: no install, no sign-up, no wait
The quiet engineering of instant play: no install, no sign-up, no waitOpen a game on your phone and count what happens before you actually play. There is usually a store page, a download, a progress bar, a permissions screen, an account form, a tutorial you cannot skip, and then, eventually, the game. Each of those steps is small on its own. Together they are a wall, and most players bounce off it before ever reaching the fun part.Instant play is the opposite philosophy. You click, and the
GST Reconciliation Software: GSTBot
The GSTR‑2B Reconciliation EngineGSTBot solves the most labor‑intensive part of the Indian GST workflow: reconciling the purchase register with the GSTR‑2B return that the tax department publishes each month. Manual reconciliation is a month‑long exercise for small‑business finance teams; GSTBot replaces that with a deterministic, configurable algorithm that runs in seconds. This is where gst reconciliation software pays off in practice. The problemA typical SMB records hundreds of p
Why I built a whiteboard for practising system design
System-design interviews ask you to draw boxes and defend them. Most of us practise on tools that were never built for that, and feedback depends on finding a human who'll read your diagram closely.So I built Whiteboard.ai: a real-time collaborative system-design whiteboard where an AI reviews your architecture diagram like a senior engineer. This post covers what's in it and, more usefully, the decisions underneath. I'll also be upfront about its limits, which are real. The problemA generi
How index keys affect inputs: compare DOM, row state, and parent state
When the first row is removed from a React list, do input values stay with the remaining rows? With index keys, the result depended on who owned the value.An uncontrolled input, whose value lived in the DOM, and an input backed by row-local state displayed another row's value. Inputs receiving values from parent state displayed the correct values, but their DOM nodes were still reassigned to different rows. Narrow the reproduction from existing codeThe personal project's schedule creation s
Building Cursor-style inline AI editing in React with Anky UI
A user wants a shorter paragraph. Moving that paragraph into a chat window adds a second workflow: copy the text, switch context, explain the task, copy the answer, paste it back, then remove the conversational preamble.An inline editor can keep the task in one place: select, rewrite, compare, accept. Anky UI supplies the interaction primitives for that flow. This article walks through how to connect them without giving the model direct ownership of your document.Repository: https://github.com/E
Search Results That Jump Back to an Old Query in React: Finding and Fixing the Race
The problemA developer built a search bar in React. Each time the user types a letter, the component sends a request to the server and shows the results. Most of the time it works. But sometimes the list shows results for an older, shorter search. The box says "react", and the list shows results for "r". Typing slowly hides the bug. Typing fast makes it show up again.This is a common bug, and it is easy to miss in local testing, because a local server answers almost every request at the sa
Random Number Generator: Picking 10 Giveaway Winners Nobody Can Predict (Python, Node, and the Browser)
Our marketing team ran a webinar in October and promised ten $200 vouchers to ten randomly chosen registrants. The export hit my inbox at 09:40, a CSV with 8,453 rows.Legal added two conditions before I touched it. Nobody may predict the winners, and we have to reproduce the exact draw six months later if anyone contests it.Those two conditions fight each other. Reproducible means a seed. A seed published before the draw lets anybody compute all ten names in advance. It took most of an afternoon
Shareable, Accessible, and Non-Blocking: Three Upgrades for a Client-Side Text Repeater
Most "simple tool" tutorials stop the moment the output appears on screen.But once real people start using a tool, three questions show up fast.Can I send my exact settings to a friend without retyping everything?Does this work with a screen reader, or does it just announce noise?And what happens to the UI when I push the count to ten thousand?I ran into all three while maintaining a text repeater called happy birthday 100 times, and none of the fixes needed a framework. Here is how I handled ea
Scalable React Project Structure with Vite and Tailwind CSS
Scalable React Project Structure with Vite and Tailwind CSSBuilding a React application is easy to start. Keeping it maintainable as it grows is the real challenge.As new features are added, a project can quickly become difficult to navigate. Components end up in the wrong folders, API requests are scattered across the codebase, and business logic becomes tightly coupled to the UI.A well-organized React project structure helps developers maintain clean code, reuse components, and scale app
URL-Safe Base64 vs Standard: How to Tell Them Apart
Standard Base64 uses 64 characters: A–Z, a–z, 0–9, and then + and /. Those last two are the problem. In a URL, + means space in application/x-www-form-urlencoded; / is a path separator. In a filename, / is a directory separator. So a string that is perfectly valid Base64 becomes structurally dangerous the moment you put it in a query parameter, a cookie value, or a JWT.The fix is an alphabet substitution, and it is where a surprising number of decoding failures begin. The substitution, and
Merging PDFs in the browser without uploading them: pdf-lib, lazy loading and a test that fails on any POST
I'm the developer of MakeQuickWork, a small site of free browser tools. This post is about how its Merge PDF tool works under the hood.Most "merge PDF online" sites follow the same pattern: you upload your files, a server stitches them together, and you download the result. That works, but the files you merge are often the ones you least want to hand to a stranger's server: a signed contract plus its annex, a passport scan for a visa application, a pile of receipts for an expense report.Merging