/* uses Pango to find all possible line break locations in a message and returns a PangoLogAttr array which maps to each byte of the message of length one larger than the message. This must be g_free()'d */ static PangoLogAttr * find_all_breaks(const char *message) { PangoContext *context; PangoLogAttr *a; GList *list; gint len, n_attr; g_return_val_if_fail(message != NULL, NULL); len = strlen(message); n_attr = len+1; a = g_new0(PangoLogAttr, n_attr); /* init Pango */ context = splitter_create_pango_context(); g_return_val_if_fail(context != NULL, NULL); list = pango_itemize(context, message, 0, len, NULL, NULL); if (list != NULL && list->data != NULL) pango_break(message, -1, &((PangoItem*)(list->data))->analysis, a, n_attr); return a; }
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; }
// Helper function used in the implementation of ScriptItemize HRESULT PangoItemize(const char * chars, int cInChars, int cMaxItems, SCRIPT_ITEM *pItems, int * pcItems) { SCRIPT_CACHE context = NULL; PangoAttrList * attributes_list = pango_attr_list_new(); GList * items = pango_itemize(GetPangoContext(&context), chars, 0, cInChars, attributes_list, NULL); *pcItems = g_list_length(items); if (*pcItems >= cMaxItems) { pango_attr_list_unref(attributes_list); g_list_free(items); return E_OUTOFMEMORY; } for(int i = 0; i < *pcItems; ++i) { PangoItem* item = static_cast<PangoItem*>(g_list_nth_data(items, i)); pItems[i].iCharPos = item->offset; pItems[i].a.fRTL = item->analysis.level == 1; pItems[i].a.fLayoutRTL = pItems[i].a.fRTL; // TODO: set other fields in SCRIPT_ANALYSIS as needed. pango_item_free(item); } pango_attr_list_unref(attributes_list); g_list_free(items); return S_OK; }
void _HYPlatformGraphicPane::_BuildCharGlyphs(void) { char c[] = "ACGT"; PangoAttrList* natl = pango_attr_list_new (); PangoAttribute* pafd = pango_attr_font_desc_new (theFont); pango_attr_list_insert (natl, pafd); charCachePangoItems = pango_itemize (screenPContext, c, 0, 4, natl,NULL); pango_attr_list_unref (natl); }
/* Helper function to re-itemize a string of text */ static PangoItem * itemize_text (EllipsizeState *state, const char *text, PangoAttrList *attrs) { GList *items; PangoItem *item; items = pango_itemize (state->layout->context, text, 0, strlen (text), attrs, NULL); g_assert (g_list_length (items) == 1); item = items->data; g_list_free (items); return item; }
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; }
// 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; }
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); }