Пример #1
0
/* 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;
}
Пример #2
0
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;
}
Пример #3
0
// 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;
}
Пример #4
0
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);
}
Пример #5
0
/* 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;
}
Пример #6
0
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;
}
Пример #7
0
// 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);
}