static PangoGlyph pango_font_get_glyph(PangoFont* font, PangoContext* context, gunichar wc) { PangoGlyph result = 0; gchar buffer[7]; gint length = g_unichar_to_utf8(wc, buffer); g_return_val_if_fail(length, 0); GList* items = pango_itemize(context, buffer, 0, length, NULL, NULL); if (g_list_length(items) == 1) { PangoItem* item = reinterpret_cast<PangoItem*>(items->data); PangoFont* tmpFont = item->analysis.font; item->analysis.font = font; PangoGlyphString* glyphs = pango_glyph_string_new(); pango_shape(buffer, length, &item->analysis, glyphs); item->analysis.font = tmpFont; if (glyphs->num_glyphs == 1) result = glyphs->glyphs[0].glyph; else g_warning("didn't get 1 glyph but %d", glyphs->num_glyphs); pango_glyph_string_free(glyphs); } g_list_foreach(items, (GFunc)pango_item_free, NULL); g_list_free(items); return result; }
static VALUE rpango_shape(VALUE self, VALUE text, VALUE analysis) { VALUE ret; PangoGlyphString* glyphs = pango_glyph_string_new(); StringValue(text); pango_shape(RSTRING_PTR(text), RSTRING_LEN(text), RVAL2BOXED(analysis, PANGO_TYPE_ANALYSIS), glyphs); ret = BOXED2RVAL(glyphs, PANGO_TYPE_GLYPH_STRING); pango_glyph_string_free (glyphs); return ret; }
static VALUE rg_s_shape(G_GNUC_UNUSED VALUE self, VALUE rbtext, VALUE rbanalysis) { const gchar *text = RVAL2CSTR(rbtext); long length = RSTRING_LEN(rbtext); PangoAnalysis *analysis = RVAL2PANGOANALYSIS(rbanalysis); PangoGlyphString *glyphs = pango_glyph_string_new(); pango_shape(text, length, analysis, glyphs); return rb_ensure(rpango_shape_result, (VALUE)glyphs, rpango_shape_ensure, (VALUE)glyphs); }
GList *FontSupport::layoutText(const WFont& font, const std::string& utf8, std::vector<PangoGlyphString *>& glyphs, int& width) { PANGO_LOCK; enabledFontFormats = enabledFontFormats_; FontMatch match = matchFont(font); PangoAttrList *attrs = pango_attr_list_new(); pango_context_set_font_description(context_, match.pangoFontDescription()); GList *items = pango_itemize(context_, utf8.c_str(), 0, utf8.length(), attrs, nullptr); width = 0; for (GList *elem = items; elem; elem = elem->next) { PangoItem *item = (PangoItem *)elem->data; PangoAnalysis *analysis = &item->analysis; PangoGlyphString *gl = pango_glyph_string_new(); pango_shape(utf8.c_str() + item->offset, item->length, analysis, gl); glyphs.push_back(gl); if (device_) { currentFont_ = analysis->font; WTextItem textItem = device_->measureText(WString::fromUTF8(utf8.substr(item->offset, item->length)), -1, false); width += pangoUnitsFromDouble(textItem.width()); currentFont_ = nullptr; } else width += pango_glyph_string_get_width(gl); } pango_attr_list_unref(attrs); return items; }
//__________________________________________________________________ void _HYPlatformGraphicPane::_DisplayChar (char c,int t, int l) { if (c>=40 && c<=100) { if (charCachePangoItems == NULL) { _BuildCharGlyphs(); } PangoItem * pitem = (PangoItem*) g_list_first (charCachePangoItems)->data; if (!cachedCharacterGlyphs[c-40]) { PangoGlyphString * newString = pango_glyph_string_new (); pango_shape (&c, 1, &pitem->analysis, newString); cachedCharacterGlyphs[c-40] = newString; } gdk_draw_glyphs (thePane, theContext, pitem->analysis.font,l,t,(PangoGlyphString* )cachedCharacterGlyphs[c-40]); } else { _DisplayText (c, t, l, false); } }
// Helper function used in the implementation of ScriptShape HRESULT PangoCharsToGlyph(SCRIPT_CACHE *psc, const char * chars, int cInChars, int cMaxItems, PangoGlyphString **pGlpyhs, int * pcItems) { ScriptCacheImplementation * cache = reinterpret_cast<ScriptCacheImplementation*>(*psc); PangoContext * pangoContext; cache->m_vwGraphics->GetTextStyleContext(reinterpret_cast<HDC*>(&pangoContext)); PangoAttrList * attributes_list = pango_attr_list_new(); GList * items = pango_itemize(pangoContext, chars, 0, cInChars, attributes_list, NULL); int length = g_list_length(items); int glyphsCount = 0; pGlpyhs[0] = NULL; for(int i = 0; i < length; ++i) { PangoItem* item = static_cast<PangoItem*>(g_list_nth_data(items, i)); PangoGlyphString * ptrPangoGlyphString = pango_glyph_string_new(); pango_shape(chars + item->offset, item->length, &item->analysis, ptrPangoGlyphString); glyphsCount += ptrPangoGlyphString->num_glyphs; if (glyphsCount > cMaxItems) { pango_glyph_string_free(ptrPangoGlyphString); FreeGlyphs(reinterpret_cast<WORD*>(pGlpyhs), cMaxItems); pango_item_free(item); pango_attr_list_unref(attributes_list); g_list_free(items); return E_OUTOFMEMORY; } pGlpyhs[i] = ptrPangoGlyphString; if (i < (cMaxItems - 1)) pGlpyhs[i + 1] = NULL; // null term the list (used for deleting etc.) pango_item_free(item); } pango_attr_list_unref(attributes_list); g_list_free(items); *pcItems = glyphsCount; return S_OK; }
GtkPaintContext::GtkPaintContext() { myPixmap = 0; myWidth = 0; myHeight = 0; myContext = 0; myFontDescription = 0; myAnalysis.lang_engine = 0; myAnalysis.level = 0; myAnalysis.language = 0; myAnalysis.extra_attrs = 0; myString = pango_glyph_string_new(); myTextGC = 0; myFillGC = 0; myBackGC = 0; myStringHeight = -1; mySpaceWidth = -1; }
static VALUE rglyph_initialize(VALUE self) { G_INITIALIZE(self, pango_glyph_string_new()); return Qnil; }
/* Shapes the ellipsis using the font and is_cjk information computed by * update_ellipsis_shape() from the first character in the gap. */ static void shape_ellipsis (EllipsizeState *state) { PangoAttrList *attrs = pango_attr_list_new (); GSList *run_attrs; PangoItem *item; PangoGlyphString *glyphs; GSList *l; PangoAttribute *fallback; const char *ellipsis_text; int i; /* Create/reset state->ellipsis_run */ if (!state->ellipsis_run) { state->ellipsis_run = g_slice_new (PangoGlyphItem); state->ellipsis_run->glyphs = pango_glyph_string_new (); state->ellipsis_run->item = NULL; } if (state->ellipsis_run->item) { pango_item_free (state->ellipsis_run->item); state->ellipsis_run->item = NULL; } /* Create an attribute list */ run_attrs = pango_attr_iterator_get_attrs (state->gap_start_attr); for (l = run_attrs; l; l = l->next) { PangoAttribute *attr = l->data; attr->start_index = 0; attr->end_index = G_MAXINT; pango_attr_list_insert (attrs, attr); } g_slist_free (run_attrs); fallback = pango_attr_fallback_new (FALSE); fallback->start_index = 0; fallback->end_index = G_MAXINT; pango_attr_list_insert (attrs, fallback); /* First try using a specific ellipsis character in the best matching font */ if (state->ellipsis_is_cjk) ellipsis_text = "\342\213\257"; /* U+22EF: MIDLINE HORIZONTAL ELLIPSIS, used for CJK */ else ellipsis_text = "\342\200\246"; /* U+2026: HORIZONTAL ELLIPSIS */ item = itemize_text (state, ellipsis_text, attrs); /* If that fails we use "..." in the first matching font */ if (!item->analysis.font || !_pango_engine_shape_covers (item->analysis.shape_engine, item->analysis.font, item->analysis.language, g_utf8_get_char (ellipsis_text))) { pango_item_free (item); /* Modify the fallback iter while it is inside the PangoAttrList; Don't try this at home */ ((PangoAttrInt *)fallback)->value = TRUE; ellipsis_text = "..."; item = itemize_text (state, ellipsis_text, attrs); } pango_attr_list_unref (attrs); state->ellipsis_run->item = item; /* Now shape */ glyphs = state->ellipsis_run->glyphs; pango_shape (ellipsis_text, strlen (ellipsis_text), &item->analysis, glyphs); state->ellipsis_width = 0; for (i = 0; i < glyphs->num_glyphs; i++) state->ellipsis_width += glyphs->glyphs[i].geometry.width; }
JNIEXPORT jobject JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_getGlyphVector (JNIEnv *env, jobject self, jstring chars, jobject font, jobject fontRenderContext) { struct peerfont *pfont = NULL; GList *items = NULL, *i = NULL; gchar *str = NULL; int len, j; double *native_extents; int *native_codes; jintArray java_codes = NULL; jdoubleArray java_extents = NULL; gdk_threads_enter (); pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self); g_assert (pfont != NULL); len = (*gdk_env())->GetStringUTFLength (env, chars); str = (gchar *)(*env)->GetStringUTFChars (env, chars, NULL); g_assert (str != NULL); if (attrs == NULL) attrs = pango_attr_list_new (); if (len > 0 && str[len-1] == '\0') len--; items = pango_itemize (pfont->ctx, str, 0, len, attrs, NULL); i = g_list_first (items); if (i == NULL) { java_extents = (*env)->NewDoubleArray (env, 0); java_codes = (*env)->NewIntArray (env, 0); } else { PangoGlyphString *glyphs; PangoItem *item = (PangoItem *)i->data; pango_context_set_font_description (pfont->ctx, pfont->desc); pango_context_set_language (pfont->ctx, gtk_get_default_language()); pango_context_load_font (pfont->ctx, pfont->desc); glyphs = pango_glyph_string_new (); g_assert (glyphs != NULL); pango_shape (str + item->offset, item->length, &(item->analysis), glyphs); if (glyphs->num_glyphs > 0) { int x = 0; double scale = ((double) PANGO_SCALE); java_extents = (*env)->NewDoubleArray (env, glyphs->num_glyphs * NUM_GLYPH_METRICS); java_codes = (*env)->NewIntArray (env, glyphs->num_glyphs); native_extents = (*env)->GetDoubleArrayElements (env, java_extents, NULL); native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL); for (j = 0; j < glyphs->num_glyphs; ++j) { PangoRectangle ink; PangoRectangle logical; PangoGlyphGeometry *geom = &glyphs->glyphs[j].geometry; pango_font_get_glyph_extents (pfont->font, glyphs->glyphs[j].glyph, &ink, &logical); native_codes[j] = glyphs->glyphs[j].glyph; native_extents[ GLYPH_LOG_X(j) ] = (logical.x) / scale; native_extents[ GLYPH_LOG_Y(j) ] = (- logical.y) / scale; native_extents[ GLYPH_LOG_WIDTH(j) ] = (logical.width) / scale; native_extents[ GLYPH_LOG_HEIGHT(j) ] = (logical.height) / scale; native_extents[ GLYPH_INK_X(j) ] = (ink.x) / scale; native_extents[ GLYPH_INK_Y(j) ] = (- ink.y) / scale; native_extents[ GLYPH_INK_WIDTH(j) ] = (ink.width) / scale; native_extents[ GLYPH_INK_HEIGHT(j) ] = (ink.height) / scale; native_extents[ GLYPH_POS_X(j) ] = (x + geom->x_offset) / scale; native_extents[ GLYPH_POS_Y(j) ] = ( - geom->y_offset) / scale; x += geom->width; } (*env)->ReleaseDoubleArrayElements (env, java_extents, native_extents, 0); (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0); } pango_glyph_string_free (glyphs); } (*env)->ReleaseStringUTFChars (env, chars, str); for (i = g_list_first (items); i != NULL; i = g_list_next (i)) g_free (i->data); g_list_free (items); gdk_threads_leave (); return (*env)->NewObject (env, glyphVector_class, glyphVector_ctor, java_extents, java_codes, font, fontRenderContext); }