struct TEXT_WIDGET_HANDLE text_widget_init ( float x_mm, float y_mm, float width_mm, float height_mm, float dpmm_x, float dpmm_y ) { struct TEXT_WIDGET_HANDLE handle; handle.d = malloc( sizeof( struct TEXT_WIDGET_PRIVATE ) ); handle.d->x_mm = x_mm; handle.d->y_mm = y_mm; handle.d->dpmm_x = dpmm_x; handle.d->dpmm_y = dpmm_y; handle.d->font_map = pango_ft2_font_map_new(); // Note: FreeType works in DPI. pango_ft2_font_map_set_resolution( (PangoFT2FontMap*)handle.d->font_map, dpmm_x * 25.4, dpmm_y * 25.4 ); handle.d->context = pango_font_map_create_context( handle.d->font_map ); handle.d->layout = pango_layout_new( handle.d->context ); // Pango works in Pango Units. Not exactly clear how the resolution of // the font and the size of the rendering box fit together. int width = pango_units_from_double( dpmm_x * width_mm ); int height = pango_units_from_double( dpmm_y * height_mm ); pango_layout_set_width( handle.d->layout, width ); pango_layout_set_height( handle.d->layout, height ); handle.d->foreground = vgCreatePaint(); vgSetParameterfv( handle.d->foreground, VG_PAINT_COLOR, 4, DEFAULT_FOREGROUND ); return handle; }
TextAsset::Size TextAsset::computeSizeOfText(cairo_t* cairoContext, const std::string textString, int bounds, PangoFontDescription* font, Rect* tight, float* lineHeightOut) { PangoLayout* layout = pango_cairo_create_layout(cairoContext); // Kerning PangoAttrList* attr_list = pango_attr_list_new(); PangoAttribute* spacing_attr = pango_attr_letter_spacing_new(pango_units_from_double(_kern)); pango_attr_list_insert(attr_list, spacing_attr); pango_layout_set_attributes(layout, attr_list); pango_cairo_context_set_resolution(pango_layout_get_context(layout), DISPLAY_RESOLUTION); pango_layout_set_text(layout, textString.c_str(), (int)textString.length()); pango_layout_set_alignment(layout, _alignment); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); const Size maxTextureSize(bounds, 1024); pango_layout_set_width(layout, pango_units_from_double(maxTextureSize.width)); pango_layout_set_height(layout, pango_units_from_double(maxTextureSize.height)); pango_layout_set_font_description(layout, font); applyLeading(cairoContext, layout, font); PangoRectangle estimateSize; PangoRectangle ink; pango_layout_get_pixel_extents(layout, &ink, &estimateSize); // If the text is right or center aligned the offsets will contain all the // leading space. We ignore that for the size because drawText will draw // in the larger box. The tight box below will get the offsets so we know // where to draw so the text lands in the same tight box. Size res(estimateSize.width, estimateSize.height); if (tight != NULL) { float lineHeight; float xHeight = charHeight(cairoContext, font, 'x', &lineHeight); if (lineHeightOut != NULL) { *lineHeightOut = lineHeight; } const float capHeight = charHeight(cairoContext, font, 'Y'); const float ascender = pango_units_to_double(pango_layout_get_baseline(layout)); const float topSpace = ascender - capHeight; const float bottomSpace = MAX(lineHeight - ascender - (capHeight - xHeight), 0); if (res.height > topSpace + bottomSpace) { *tight = Rect(estimateSize.x, estimateSize.y + topSpace, res.width, res.height - topSpace - bottomSpace); } else { *tight = Rect(0, 0, res.width, res.height); } } g_object_unref(layout); return res; }
void TextRenderer::OnButtonPressEvent(GdkEventButton* event) { if( event->type != GDK_BUTTON_PRESS || !IsLeftButton(event) ) return; Point lct((int)event->x, (int)event->y); lct = GetTransition().DevToRel(lct); if( CalcTextPlc().Contains(lct) ) { double x = lct.x, y = lct.y; { CairoStateSave save(caiCont); ApplyTextTrans(); caiCont->device_to_user(x, y); } int idx, trail; utf8::trans tr(GetText()); if( panLay->xy_to_index(pango_units_from_double(x), pango_units_from_double(y), idx, trail) ) { int new_pos = tr.to_offset(idx); // видимо в случае "сложных" букв trail может принимать и отличные от // {0, 1} значения (восточные иероглифы?), но нам требуется точность до целого символа if( trail ) new_pos++; MoveCursor( new_pos ); } else MoveCursor( tr.length() ); } }
static void e_contact_output (GtkPrintContext *context, PangoFontDescription *font, gdouble x, gdouble y, gdouble width, const gchar *text) { PangoLayout *layout; gdouble indent; cairo_t *cr; layout = gtk_print_context_create_pango_layout (context); if (width == -1 || get_font_width (context, font, text) <= width) indent = .0; else indent = get_font_width (context, font, " "); pango_layout_set_font_description (layout, font); pango_layout_set_text (layout, text, -1); pango_layout_set_width (layout, pango_units_from_double (width)); pango_layout_set_indent (layout, pango_units_from_double (indent)); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); cr = gtk_print_context_get_cairo_context (context); cairo_save (cr); cairo_move_to (cr, x, y); pango_cairo_show_layout (cr, layout); cairo_restore (cr); g_object_unref (layout); }
/** * pango_matrix_transform_rectangle: * @matrix: a #PangoMatrix, or %NULL * @rect: (inout) (allow-none): in/out bounding box in Pango units, or %NULL * * First transforms @rect using @matrix, then calculates the bounding box * of the transformed rectangle. The rectangle should be in Pango units. * * This function is useful for example when you want to draw a rotated * @PangoLayout to an image buffer, and want to know how large the image * should be and how much you should shift the layout when rendering. * * If you have a rectangle in device units (pixels), use * pango_matrix_transform_pixel_rectangle(). * * If you have the rectangle in Pango units and want to convert to * transformed pixel bounding box, it is more accurate to transform it first * (using this function) and pass the result to pango_extents_to_pixels(), * first argument, for an inclusive rounded rectangle. * However, there are valid reasons that you may want to convert * to pixels first and then transform, for example when the transformed * coordinates may overflow in Pango units (large matrix translation for * example). * * Since: 1.16 **/ void pango_matrix_transform_rectangle (const PangoMatrix *matrix, PangoRectangle *rect) { int i; double quad_x[4], quad_y[4]; double dx1, dy1; double dx2, dy2; double min_x, max_x; double min_y, max_y; if (!rect || !matrix) return; quad_x[0] = pango_units_to_double (rect->x); quad_y[0] = pango_units_to_double (rect->y); pango_matrix_transform_point (matrix, &quad_x[0], &quad_y[0]); dx1 = pango_units_to_double (rect->width); dy1 = 0; pango_matrix_transform_distance (matrix, &dx1, &dy1); quad_x[1] = quad_x[0] + dx1; quad_y[1] = quad_y[0] + dy1; dx2 = 0; dy2 = pango_units_to_double (rect->height); pango_matrix_transform_distance (matrix, &dx2, &dy2); quad_x[2] = quad_x[0] + dx2; quad_y[2] = quad_y[0] + dy2; quad_x[3] = quad_x[0] + dx1 + dx2; quad_y[3] = quad_y[0] + dy1 + dy2; min_x = max_x = quad_x[0]; min_y = max_y = quad_y[0]; for (i=1; i < 4; i++) { if (quad_x[i] < min_x) min_x = quad_x[i]; else if (quad_x[i] > max_x) max_x = quad_x[i]; if (quad_y[i] < min_y) min_y = quad_y[i]; else if (quad_y[i] > max_y) max_y = quad_y[i]; } rect->x = pango_units_from_double (min_x); rect->y = pango_units_from_double (min_y); rect->width = pango_units_from_double (max_x) - rect->x; rect->height = pango_units_from_double (max_y) - rect->y; }
static PyObject * _pango_layout_set_width_height(PyObject *self, PyObject *args) { PangoLayout *layout; int width, height; if (!PyArg_ParseTuple(args, "lii", &layout, &width, &height)) return NULL; pango_layout_set_width(layout, pango_units_from_double(width)); pango_layout_set_height(layout, pango_units_from_double(height)); Py_RETURN_NONE; }
void TextAsset::drawText(cairo_t* cairoContext, const std::string& textString, const Rect& rect, PangoFontDescription* inFontDescription, bool outlineEnabled) { cairo_move_to(cairoContext, rect.x, rect.y); PangoLayout* layout = pango_cairo_create_layout(cairoContext); // Kerning PangoAttrList* attr_list = pango_attr_list_new(); PangoAttribute* spacing_attr = pango_attr_letter_spacing_new(pango_units_from_double(_kern)); pango_attr_list_insert(attr_list, spacing_attr); pango_layout_set_attributes(layout, attr_list); pango_cairo_context_set_resolution(pango_layout_get_context(layout), DISPLAY_RESOLUTION); pango_layout_set_text(layout, textString.c_str(), textString.length()); pango_layout_set_font_description(layout, inFontDescription); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_width(layout, pango_units_from_double(rect.size.width + WIDTH_PADDING)); pango_layout_set_height(layout, pango_units_from_double(rect.size.height + HEIGHT_PADDING)); pango_layout_set_alignment(layout, _alignment); applyLeading(cairoContext, layout, inFontDescription); pango_cairo_show_layout(cairoContext, layout); // Core Text defines positive outline width values as stroke only if (_outlineThickness <= 0.0f) { cairo_fill_preserve(cairoContext); } // Outline if (outlineEnabled && _outlineThickness != 0.0f) { const float outlineThickness = (fabsf(_outlineThickness) / 100.0f) * _fontSize * CLIENT_TO_SERVER_SCALE; cairo_set_source_rgba(cairoContext, _outlineColor.red, _outlineColor.green, _outlineColor.blue, _outlineColor.alpha); pango_cairo_layout_path(cairoContext, layout); cairo_set_line_width(cairoContext, outlineThickness); cairo_stroke(cairoContext); } else { cairo_new_path(cairoContext); } g_object_unref(layout); }
static PangoLayout * make_new_page (PangoContext * context, PangoFontDescription * desc, gdouble height, gdouble width) { PangoLayout *layout; layout = pango_layout_new (context); pango_layout_set_justify (layout, TRUE); pango_layout_set_spacing (layout, 1.5 * PANGO_SCALE); pango_layout_set_width (layout, pango_units_from_double(width - SIDE_MARGIN)); pango_layout_set_height (layout, pango_units_from_double(height - EDGE_MARGIN)); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_font_description (layout, desc); return layout; }
void TextAsset::applyLeading(cairo_t* cairoContext, PangoLayout* layout, PangoFontDescription* font) const { float lineHeight; charHeight(cairoContext, font, 'a', &lineHeight); const float lineSpacing = (_leadingMultiplier - 1.0) * lineHeight; pango_layout_set_spacing(layout, pango_units_from_double(lineSpacing)); }
void PrintNotesNoteAddin::on_begin_print(const Glib::RefPtr<Gtk::PrintContext>& context) { m_timestamp_footer = create_layout_for_timestamp(context); // Create and initialize the page margins m_margin_top = cm_to_pixel (1.5, context->get_dpi_y()); m_margin_left = cm_to_pixel (1, context->get_dpi_x()); m_margin_right = cm_to_pixel (1, context->get_dpi_x()); m_margin_bottom = 0; double max_height = pango_units_from_double(context->get_height() - m_margin_top - m_margin_bottom - compute_footer_height(context)); DBG_OUT("margins = %d %d %d %d", m_margin_top, m_margin_left, m_margin_right, m_margin_bottom); m_page_breaks.clear(); Gtk::TextIter position; Gtk::TextIter end_iter; get_buffer()->get_bounds (position, end_iter); double page_height = 0; bool done = position.compare (end_iter) >= 0; while (!done) { Gtk::TextIter line_end = position; if (!line_end.ends_line ()) { line_end.forward_to_line_end (); } int paragraph_number = position.get_line(); int indentation = 0; Glib::RefPtr<Pango::Layout> layout = create_layout_for_paragraph( context, position, line_end, indentation); Pango::Rectangle ink_rect; Pango::Rectangle logical_rect; for(int line_in_paragraph = 0; line_in_paragraph < layout->get_line_count(); line_in_paragraph++) { Glib::RefPtr<Pango::LayoutLine> line = layout->get_line(line_in_paragraph); line->get_extents (ink_rect, logical_rect); if ((page_height + logical_rect.get_height()) >= max_height) { PageBreak(paragraph_number, line_in_paragraph); m_page_breaks.push_back (PageBreak(paragraph_number, line_in_paragraph)); page_height = 0; } page_height += logical_rect.get_height(); } position.forward_line (); done = position.compare (end_iter) >= 0; } m_print_op->set_n_pages(m_page_breaks.size() + 1); }
Glib::RefPtr<Pango::Layout> PrintNotesNoteAddin::create_layout_for_paragraph(const Glib::RefPtr<Gtk::PrintContext> & context, Gtk::TextIter p_start, Gtk::TextIter p_end, int & indentation) { Glib::RefPtr<Pango::Layout> layout = context->create_pango_layout(); layout->set_font_description( get_window()->editor()->get_pango_context()->get_font_description()); int start_index = p_start.get_line_index(); indentation = 0; double dpiX = context->get_dpi_x(); { Pango::AttrList attr_list; Gtk::TextIter segm_start = p_start; Gtk::TextIter segm_end; while (segm_start.compare (p_end) < 0) { segm_end = segm_start; std::list<Pango::Attribute> attrs; get_paragraph_attributes (layout, dpiX, indentation, segm_end, p_end, attrs); guint si = (guint) (segm_start.get_line_index() - start_index); guint ei = (guint) (segm_end.get_line_index() - start_index); for(std::list<Pango::Attribute>::iterator iter = attrs.begin(); iter != attrs.end(); ++iter) { Pango::Attribute & a(*iter); a.set_start_index(si); a.set_end_index(ei); attr_list.insert(a); } segm_start = segm_end; } layout->set_attributes(attr_list); } gnote::DepthNoteTag::Ptr depth = get_buffer()->find_depth_tag(p_start); if(depth) { indentation += ((int) (dpiX / 3)) * depth->get_depth(); } layout->set_width(pango_units_from_double((int)context->get_width() - m_margin_left - m_margin_right - indentation)); layout->set_wrap (Pango::WRAP_WORD_CHAR); layout->set_text (get_buffer()->get_slice (p_start, p_end, false)); return layout; }
static gboolean _pango_cairo_font_private_glyph_extents_cache_init (PangoCairoFontPrivate *cf_priv) { cairo_scaled_font_t *scaled_font = _pango_cairo_font_private_get_scaled_font (cf_priv); cairo_font_extents_t font_extents; if (G_UNLIKELY (scaled_font == NULL || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS)) return FALSE; cairo_scaled_font_extents (scaled_font, &font_extents); cf_priv->font_extents.x = 0; cf_priv->font_extents.width = 0; cf_priv->font_extents.height = pango_units_from_double (font_extents.ascent + font_extents.descent); switch (cf_priv->gravity) { default: case PANGO_GRAVITY_AUTO: case PANGO_GRAVITY_SOUTH: cf_priv->font_extents.y = - pango_units_from_double (font_extents.ascent); break; case PANGO_GRAVITY_NORTH: cf_priv->font_extents.y = - pango_units_from_double (font_extents.descent); break; case PANGO_GRAVITY_EAST: case PANGO_GRAVITY_WEST: { int ascent = pango_units_from_double (font_extents.ascent + font_extents.descent) / 2; if (cf_priv->is_hinted) ascent = PANGO_UNITS_ROUND (ascent); cf_priv->font_extents.y = - ascent; } } cf_priv->glyph_extents_cache = g_new0 (PangoCairoFontGlyphExtentsCacheEntry, GLYPH_CACHE_NUM_ENTRIES); /* Make sure all cache entries are invalid initially */ cf_priv->glyph_extents_cache[0].glyph = 1; /* glyph 1 cannot happen in bucket 0 */ return TRUE; }
/* Fills in the glyph extents cache entry */ static void compute_glyph_extents (PangoCairoFontPrivate *cf_priv, PangoGlyph glyph, PangoCairoFontGlyphExtentsCacheEntry *entry) { cairo_text_extents_t extents; cairo_glyph_t cairo_glyph; cairo_glyph.index = glyph; cairo_glyph.x = 0; cairo_glyph.y = 0; cairo_scaled_font_glyph_extents (_pango_cairo_font_private_get_scaled_font (cf_priv), &cairo_glyph, 1, &extents); entry->glyph = glyph; entry->width = pango_units_from_double (extents.x_advance); entry->ink_rect.x = pango_units_from_double (extents.x_bearing); entry->ink_rect.y = pango_units_from_double (extents.y_bearing); entry->ink_rect.width = pango_units_from_double (extents.width); entry->ink_rect.height = pango_units_from_double (extents.height); }
Glib::RefPtr<Pango::Layout> PrintNotesNoteAddin::create_layout_for_timestamp(const Glib::RefPtr<Gtk::PrintContext> & context) { Glib::ustring timestamp = sharp::DateTime::now().to_string("%c"); Glib::RefPtr<Pango::Layout> layout = context->create_pango_layout (); Pango::FontDescription font_desc = get_window()->editor()->get_pango_context()->get_font_description(); font_desc.set_style(Pango::STYLE_NORMAL); font_desc.set_weight(Pango::WEIGHT_LIGHT); layout->set_font_description(font_desc); layout->set_width(pango_units_from_double((int) context->get_width())); layout->set_alignment(Pango::ALIGN_RIGHT); layout->set_text (timestamp); return layout; }
Glib::RefPtr<Pango::Layout> PrintNotesNoteAddin::create_layout_for_pagenumbers(const Glib::RefPtr<Gtk::PrintContext> & context, int page_number, int total_pages) { Glib::RefPtr<Pango::Layout> layout = context->create_pango_layout(); Pango::FontDescription font_desc = get_window()->editor()->get_pango_context()->get_font_description(); font_desc.set_style(Pango::STYLE_NORMAL); font_desc.set_weight(Pango::WEIGHT_LIGHT); layout->set_font_description(font_desc); layout->set_width(pango_units_from_double((int)context->get_width())); // %1 is the page number, %2 is the total number of pages Glib::ustring footer_left = Glib::ustring::compose(_("Page %1 of %2"), page_number, total_pages); layout->set_alignment(Pango::ALIGN_LEFT); layout->set_text (footer_left); return layout; }
void SetFontSize(Pango::FontDescription& dsc, double sz) { dsc.set_size(pango_units_from_double(sz)); }
static PangoCairoFontHexBoxInfo * _pango_cairo_font_private_get_hex_box_info (PangoCairoFontPrivate *cf_priv) { static const char hexdigits[] = "0123456789ABCDEF"; char c[2] = {0, 0}; PangoFont *mini_font; PangoCairoFontHexBoxInfo *hbi; /* for metrics hinting */ double scale_x = 1., scale_x_inv = 1., scale_y = 1., scale_y_inv = 1.; gboolean is_hinted; int i; int rows; double pad; double width = 0; double height = 0; cairo_font_options_t *font_options; cairo_font_extents_t font_extents; double size, mini_size; PangoFontDescription *desc; cairo_scaled_font_t *scaled_font, *scaled_mini_font; PangoMatrix pango_ctm; cairo_matrix_t cairo_ctm; PangoGravity gravity; if (!cf_priv) return NULL; if (cf_priv->hbi) return cf_priv->hbi; scaled_font = _pango_cairo_font_private_get_scaled_font (cf_priv); if (G_UNLIKELY (scaled_font == NULL || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS)) return NULL; is_hinted = cf_priv->is_hinted; font_options = cairo_font_options_create (); desc = pango_font_describe_with_absolute_size ((PangoFont *)cf_priv->cfont); size = pango_font_description_get_size (desc) / (1.*PANGO_SCALE); gravity = pango_font_description_get_gravity (desc); cairo_scaled_font_get_ctm (scaled_font, &cairo_ctm); cairo_scaled_font_get_font_options (scaled_font, font_options); /* I started adding support for vertical hexboxes here, but it's too much * work. Easier to do with cairo user fonts and vertical writing mode * support in cairo. */ /*cairo_matrix_rotate (&cairo_ctm, pango_gravity_to_rotation (gravity));*/ pango_ctm.xx = cairo_ctm.xx; pango_ctm.yx = cairo_ctm.yx; pango_ctm.xy = cairo_ctm.xy; pango_ctm.yy = cairo_ctm.yy; pango_ctm.x0 = cairo_ctm.x0; pango_ctm.y0 = cairo_ctm.y0; if (is_hinted) { /* prepare for some hinting */ double x, y; x = 1.; y = 0.; cairo_matrix_transform_distance (&cairo_ctm, &x, &y); scale_x = sqrt (x*x + y*y); scale_x_inv = 1 / scale_x; x = 0.; y = 1.; cairo_matrix_transform_distance (&cairo_ctm, &x, &y); scale_y = sqrt (x*x + y*y); scale_y_inv = 1 / scale_y; } /* we hint to the nearest device units */ #define HINT(value, scale, scale_inv) (ceil ((value-1e-5) * scale) * scale_inv) #define HINT_X(value) HINT ((value), scale_x, scale_x_inv) #define HINT_Y(value) HINT ((value), scale_y, scale_y_inv) /* create mini_font description */ { PangoFontMap *fontmap; PangoContext *context; /* XXX this is racy. need a ref'ing getter... */ fontmap = pango_font_get_font_map ((PangoFont *)cf_priv->cfont); if (!fontmap) return NULL; fontmap = g_object_ref (fontmap); /* we inherit most font properties for the mini font. just * change family and size. means, you get bold hex digits * in the hexbox for a bold font. */ /* We should rotate the box, not glyphs */ pango_font_description_unset_fields (desc, PANGO_FONT_MASK_GRAVITY); pango_font_description_set_family_static (desc, "monospace"); rows = 2; mini_size = size / 2.2; if (is_hinted) { mini_size = HINT_Y (mini_size); if (mini_size < 6.0) { rows = 1; mini_size = MIN (MAX (size - 1, 0), 6.0); } } pango_font_description_set_absolute_size (desc, pango_units_from_double (mini_size)); /* load mini_font */ context = pango_font_map_create_context (fontmap); pango_context_set_matrix (context, &pango_ctm); pango_context_set_language (context, pango_script_get_sample_language (PANGO_SCRIPT_LATIN)); pango_cairo_context_set_font_options (context, font_options); mini_font = pango_font_map_load_font (fontmap, context, desc); g_object_unref (context); g_object_unref (fontmap); } pango_font_description_free (desc); cairo_font_options_destroy (font_options); scaled_mini_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *) mini_font); for (i = 0 ; i < 16 ; i++) { cairo_text_extents_t extents; c[0] = hexdigits[i]; cairo_scaled_font_text_extents (scaled_mini_font, c, &extents); width = MAX (width, extents.width); height = MAX (height, extents.height); } cairo_scaled_font_extents (scaled_font, &font_extents); if (font_extents.ascent + font_extents.descent <= 0) { font_extents.ascent = PANGO_UNKNOWN_GLYPH_HEIGHT; font_extents.descent = 0; } pad = (font_extents.ascent + font_extents.descent) / 43; pad = MIN (pad, mini_size); hbi = g_slice_new (PangoCairoFontHexBoxInfo); hbi->font = (PangoCairoFont *) mini_font; hbi->rows = rows; hbi->digit_width = width; hbi->digit_height = height; hbi->pad_x = pad; hbi->pad_y = pad; if (is_hinted) { hbi->digit_width = HINT_X (hbi->digit_width); hbi->digit_height = HINT_Y (hbi->digit_height); hbi->pad_x = HINT_X (hbi->pad_x); hbi->pad_y = HINT_Y (hbi->pad_y); } hbi->line_width = MIN (hbi->pad_x, hbi->pad_y); hbi->box_height = 3 * hbi->pad_y + rows * (hbi->pad_y + hbi->digit_height); if (rows == 1 || hbi->box_height <= font_extents.ascent) { hbi->box_descent = 2 * hbi->pad_y; } else if (hbi->box_height <= font_extents.ascent + font_extents.descent - 2 * hbi->pad_y) { hbi->box_descent = 2 * hbi->pad_y + hbi->box_height - font_extents.ascent; } else { hbi->box_descent = font_extents.descent * hbi->box_height / (font_extents.ascent + font_extents.descent); } if (is_hinted) { hbi->box_descent = HINT_Y (hbi->box_descent); } cf_priv->hbi = hbi; return hbi; }