📄 pangoft2-render.c
字号:
dest = bitmap->buffer + iy * bitmap->pitch; if (t->x1 < b->x1) x1 = floor (t->x1); else x1 = floor (b->x1); if (t->x2 > b->x2) x2 = ceil (t->x2); else x2 = ceil (b->x2); x1 = CLAMP (x1, 0, bitmap->width); x2 = CLAMP (x2, 0, bitmap->width); for (x = x1; x < x2; x++) { double top_left = MAX (t->x1, x); double top_right = MIN (t->x2, x + 1); double bottom_left = MAX (b->x1, x); double bottom_right = MIN (b->x2, x + 1); double c = 0.5 * dy * ((top_right - top_left) + (bottom_right - bottom_left)); /* When converting to [0,255], we round up. This is intended * to prevent the problem of pixels that get divided into * multiple slices not being fully black. */ int ic = c * 256; dest[x] = MIN (dest[x] + ic, 255); }}static voidinterpolate_position (Position *result, Position *top, Position *bottom, double val, double val1, double val2){ result->y = (top->y * (val2 - val) + bottom->y * (val - val1)) / (val2 - val1); result->x1 = (top->x1 * (val2 - val) + bottom->x1 * (val - val1)) / (val2 - val1); result->x2 = (top->x2 * (val2 - val) + bottom->x2 * (val - val1)) / (val2 - val1);}/* This draws a trapezoid with the parallel sides aligned with * the X axis. We do this by subdividing the trapezoid vertically * into thin slices (themselves trapezoids) where two edge sides are each * contained within a single pixel and then rasterizing each * slice. There are frequently multiple slices within a single * line so we have to accumulate to get the final result. */static voidpango_ft2_renderer_draw_trapezoid (PangoRenderer *renderer, PangoRenderPart part, double y1, double x11, double x21, double y2, double x12, double x22){ Position pos; Position t; Position b; gboolean done = FALSE; if (y1 == y2) return; pos.y = t.y = y1; pos.x1 = t.x1 = x11; pos.x2 = t.x2 = x21; b.y = y2; b.x1 = x12; b.x2 = x22; while (!done) { Position pos_next; double y_next, x1_next, x2_next; double ix1, ix2; /* The algorithm here is written to emphasize simplicity and * numerical stability as opposed to speed. * * While the end result is slicing up the polygon vertically, * conceptually we aren't walking in the X direction, rather we * are walking along the edges. When we compute crossing of * horizontal pixel boundaries, we use the X coordinate as the * interpolating variable, when we compute crossing for vertical * pixel boundaries, we use the Y coordinate. * * This allows us to handle almost exactly horizontal edges without * running into difficulties. (Almost exactly horizontal edges * come up frequently due to inexactness in computing, say, * a 90 degree rotation transformation) */ pos_next = b; done = TRUE; /* Check for crossing vertical pixel boundaries */ y_next = floor (pos.y) + 1; if (y_next < pos_next.y) { interpolate_position (&pos_next, &t, &b, y_next, t.y, b.y); pos_next.y = y_next; done = FALSE; } /* Check left side for crossing horizontal pixel boundaries */ ix1 = floor (pos.x1); if (b.x1 < t.x1) { if (ix1 == pos.x1) x1_next = ix1 - 1; else x1_next = ix1; if (x1_next > pos_next.x1) { interpolate_position (&pos_next, &t, &b, x1_next, t.x1, b.x1); pos_next.x1 = x1_next; done = FALSE; } } else if (b.x1 > t.x1) { x1_next = ix1 + 1; if (x1_next < pos_next.x1) { interpolate_position (&pos_next, &t, &b, x1_next, t.x1, b.x1); pos_next.x1 = x1_next; done = FALSE; } } /* Check right side for crossing horizontal pixel boundaries */ ix2 = floor (pos.x2); if (b.x2 < t.x2) { if (ix2 == pos.x2) x2_next = ix2 - 1; else x2_next = ix2; if (x2_next > pos_next.x2) { interpolate_position (&pos_next, &t, &b, x2_next, t.x2, b.x2); pos_next.x2 = x2_next; done = FALSE; } } else if (x22 > x21) { x2_next = ix2 + 1; if (x2_next < pos_next.x2) { interpolate_position (&pos_next, &t, &b, x2_next, t.x2, b.x2); pos_next.x2 = x2_next; done = FALSE; } } draw_simple_trap (renderer, &pos, &pos_next); pos = pos_next; }}/** * pango_ft2_render_layout_subpixel: * @bitmap: a <type>FT_Bitmap</type> to render the layout onto * @layout: a #PangoLayout * @x: the X position of the left of the layout (in Pango units) * @y: the Y position of the top of the layout (in Pango units) * * Render a #PangoLayout onto a FreeType2 bitmap, with he * location specified in fixed-point Pango units rather than * pixels. (Using this will avoid extra inaccuracies from * rounding to integer pixels multiple times, even if the * final glyph positions are integers.) * * Since: 1.6 */voidpango_ft2_render_layout_subpixel (FT_Bitmap *bitmap, PangoLayout *layout, int x, int y){ PangoContext *context; PangoFontMap *fontmap; PangoRenderer *renderer; g_return_if_fail (bitmap != NULL); g_return_if_fail (PANGO_IS_LAYOUT (layout)); context = pango_layout_get_context (layout); fontmap = pango_context_get_font_map (context); renderer = _pango_ft2_font_map_get_renderer (PANGO_FT2_FONT_MAP (fontmap)); pango_ft2_renderer_set_bitmap (PANGO_FT2_RENDERER (renderer), bitmap); pango_renderer_draw_layout (renderer, layout, x, y);}/** * pango_ft2_render_layout: * @bitmap: a <type>FT_Bitmap</type> to render the layout onto * @layout: a #PangoLayout * @x: the X position of the left of the layout (in pixels) * @y: the Y position of the top of the layout (in pixels) * * Render a #PangoLayout onto a FreeType2 bitmap */voidpango_ft2_render_layout (FT_Bitmap *bitmap, PangoLayout *layout, int x, int y){ pango_ft2_render_layout_subpixel (bitmap, layout, x * PANGO_SCALE, y * PANGO_SCALE);}/** * pango_ft2_render_layout_line_subpixel: * @bitmap: a <type>FT_Bitmap</type> to render the line onto * @line: a #PangoLayoutLine * @x: the x position of start of string (in Pango units) * @y: the y position of baseline (in Pango units) * * Render a #PangoLayoutLine onto a FreeType2 bitmap, with he * location specified in fixed-point Pango units rather than * pixels. (Using this will avoid extra inaccuracies from * rounding to integer pixels multiple times, even if the * final glyph positions are integers.) * * Since: 1.6 */voidpango_ft2_render_layout_line_subpixel (FT_Bitmap *bitmap, PangoLayoutLine *line, int x, int y){ PangoContext *context; PangoFontMap *fontmap; PangoRenderer *renderer; g_return_if_fail (bitmap != NULL); g_return_if_fail (line != NULL); context = pango_layout_get_context (line->layout); fontmap = pango_context_get_font_map (context); renderer = _pango_ft2_font_map_get_renderer (PANGO_FT2_FONT_MAP (fontmap)); pango_ft2_renderer_set_bitmap (PANGO_FT2_RENDERER (renderer), bitmap); pango_renderer_draw_layout_line (renderer, line, x, y);}/** * pango_ft2_render_layout_line: * @bitmap: a <type>FT_Bitmap</type> to render the line onto * @line: a #PangoLayoutLine * @x: the x position of start of string (in pixels) * @y: the y position of baseline (in pixels) * * Render a #PangoLayoutLine onto a FreeType2 bitmap */voidpango_ft2_render_layout_line (FT_Bitmap *bitmap, PangoLayoutLine *line, int x, int y){ pango_ft2_render_layout_line_subpixel (bitmap, line, x * PANGO_SCALE, y * PANGO_SCALE);}/** * pango_ft2_render_transformed: * @bitmap: the FreeType2 bitmap onto which to draw the string * @font: the font in which to draw the string * @matrix: a #PangoMatrix, or %NULL to use an identity transformation * @glyphs: the glyph string to draw * @x: the x position of the start of the string (in Pango * units in user space coordinates) * @y: the y position of the baseline (in Pango units * in user space coordinates) * * Renders a #PangoGlyphString onto a FreeType2 bitmap, possibly * transforming the layed-out coordinates through a transformation * matrix. Note that the transformation matrix for @font is not * changed, so to produce correct rendering results, the @font * must have been loaded using a #PangoContext with an identical * transformation matrix to that passed in to this function. * * Since: 1.6 **/voidpango_ft2_render_transformed (FT_Bitmap *bitmap, const PangoMatrix *matrix, PangoFont *font, PangoGlyphString *glyphs, int x, int y){ PangoFontMap *fontmap; PangoRenderer *renderer; g_return_if_fail (bitmap != NULL); g_return_if_fail (glyphs != NULL); g_return_if_fail (PANGO_FT2_IS_FONT (font)); fontmap = PANGO_FC_FONT (font)->fontmap; renderer = _pango_ft2_font_map_get_renderer (PANGO_FT2_FONT_MAP (fontmap)); pango_ft2_renderer_set_bitmap (PANGO_FT2_RENDERER (renderer), bitmap); pango_renderer_set_matrix (renderer, matrix); pango_renderer_draw_glyphs (renderer, font, glyphs, x, y);}/** * pango_ft2_render: * @bitmap: the FreeType2 bitmap onto which to draw the string * @font: the font in which to draw the string * @glyphs: the glyph string to draw * @x: the x position of the start of the string (in pixels) * @y: the y position of the baseline (in pixels) * * Renders a #PangoGlyphString onto a FreeType2 bitmap. **/voidpango_ft2_render (FT_Bitmap *bitmap, PangoFont *font, PangoGlyphString *glyphs, int x, int y){ pango_ft2_render_transformed (bitmap, NULL, font, glyphs, x * PANGO_SCALE, y * PANGO_SCALE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -