| /* | |
| * Copyright © 2026 Behdad Esfahbod | |
| * | |
| * This is part of HarfBuzz, a text shaping library. | |
| * | |
| * Permission is hereby granted, without written agreement and without | |
| * license or royalty fees, to use, copy, modify, and distribute this | |
| * software and its documentation for any purpose, provided that the | |
| * above copyright notice and the following two paragraphs appear in | |
| * all copies of this software. | |
| * | |
| * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR | |
| * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES | |
| * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN | |
| * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH | |
| * DAMAGE. | |
| * | |
| * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, | |
| * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
| * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | |
| * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO | |
| * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
| * | |
| * Author(s): Behdad Esfahbod | |
| */ | |
| #ifndef HELPER_EXTENTS_OVERLAY_HH | |
| #define HELPER_EXTENTS_OVERLAY_HH | |
| #include <hb.h> | |
| #include <math.h> | |
| /* --show-extents overlay helpers: a stroked rectangle around | |
| * each glyph's ink box, plus a filled dot at the glyph's pen | |
| * origin. Both render in the foreground color. | |
| * | |
| * In DRAW mode, the geometry goes straight into the glyph's | |
| * draw context so it gets rendered/encoded alongside the | |
| * outline in the foreground color. | |
| * | |
| * In PAINT mode, the same geometry feeds an arbitrary-path | |
| * clip and the clipped region is filled with the paint's | |
| * current foreground; the draw-mode and paint-mode emitters | |
| * share all of the coord math. */ | |
| static inline void | |
| util_emit_extents_overlay_into_draw (hb_draw_funcs_t *df, void *dd, | |
| const hb_glyph_extents_t *ge, | |
| float pen_x, float pen_y, | |
| float stroke_width) | |
| { | |
| hb_draw_state_t st = HB_DRAW_STATE_DEFAULT; | |
| /* Stroked rectangle around the ink box. Padded outward by | |
| * stroke_width / 2 so the stroke's inner edge sits at the | |
| * box, instead of straddling it (and the inner half | |
| * knocking out against glyph ink under non-zero winding). | |
| * copysignf on the padding keeps the shift outward | |
| * regardless of glyph-extent height-sign convention. */ | |
| if (ge->width != 0 || ge->height != 0) | |
| { | |
| float half = 0.5f * stroke_width; | |
| float sx = copysignf (half, ge->width ? (float) ge->width : 1.f); | |
| float sy = copysignf (half, ge->height ? (float) ge->height : 1.f); | |
| hb_draw_rectangle (df, dd, &st, | |
| pen_x + (float) ge->x_bearing - sx, | |
| pen_y + (float) ge->y_bearing - sy, | |
| (float) ge->width + 2 * sx, | |
| (float) ge->height + 2 * sy, | |
| stroke_width); | |
| } | |
| /* Filled dot at the glyph origin (pen_x, pen_y). Radius | |
| * scales with stroke_width so the dot stays visible at the | |
| * same render scale the stroke does. */ | |
| hb_draw_circle (df, dd, &st, | |
| pen_x, pen_y, | |
| /*radius*/ 2.f * stroke_width, | |
| /*stroke_width*/ NAN); | |
| } | |
| static inline void | |
| util_emit_extents_overlay_into_paint (hb_paint_funcs_t *pf, void *pd, | |
| const hb_glyph_extents_t *ge, | |
| float pen_x, float pen_y, | |
| float stroke_width) | |
| { | |
| void *dd = nullptr; | |
| hb_draw_funcs_t *df = hb_paint_push_clip_path_start (pf, pd, &dd); | |
| if (!df) return; | |
| util_emit_extents_overlay_into_draw (df, dd, ge, pen_x, pen_y, stroke_width); | |
| hb_paint_push_clip_path_end (pf, pd); | |
| hb_paint_color (pf, pd, /*is_foreground*/ 1, HB_COLOR (0, 0, 0, 255)); | |
| hb_paint_pop_clip (pf, pd); | |
| } | |
| #endif /* HELPER_EXTENTS_OVERLAY_HH */ |