static VALUE
layout_iter_get_char_extents(VALUE self)
{
    PangoRectangle logical_rect;
    
    pango_layout_iter_get_char_extents(_SELF(self), &logical_rect);
    return BOXED2RVAL(&logical_rect, PANGO_TYPE_RECTANGLE);
}
示例#2
0
static gboolean 
gw_spellcheck_get_line_coordinates (GwSpellcheck *spellcheck, int startindex, int endindex, int *x, int *y, int *x2, int *y2)
{
    //Declarations
    GwSpellcheckPrivate *priv;
    int index;
    PangoLayout *layout;
    PangoRectangle rect;
    PangoLayoutIter *iter;
    int xoffset, yoffset;

    //Initializations
    priv = spellcheck->priv;
    layout = gtk_entry_get_layout (priv->entry);
    iter = pango_layout_get_iter (layout);
    xoffset = gw_spellcheck_get_layout_x_offset (spellcheck);
    yoffset = gw_spellcheck_get_layout_y_offset (spellcheck);
    *x = *y = *x2 = *y2 = 0;

    do {
      index = pango_layout_iter_get_index (iter);
      pango_layout_iter_get_char_extents  (iter, &rect);
      if (index == startindex)
      {
        *x = PANGO_PIXELS (rect.x) + xoffset;
        *y = PANGO_PIXELS (rect.y + rect.height) + yoffset;
      }
      if (index == endindex - 1)
      {
        *x2 = PANGO_PIXELS (rect.width + rect.x) + xoffset + 1;
        *y2 = *y;
      }
    } while (pango_layout_iter_next_char (iter));

    //Cleanup
    pango_layout_iter_free (iter);

    return (*x > 0 && *y > 0 && *x2 > 0 && *y2 > 0);
}
示例#3
0
static PyObject *
pango_GetLayoutClusterPos(PyObject *self, PyObject *args) {

	int i, len, w, h, index, prev_index;
	int ltr_flag, rtl_flag;
	double baseline, x, y, width, height, char_width, dx, dy;
	void *LayoutObj;
	PangoLayout *layout;
	PangoLayoutIter *iter;
	PangoLayoutIter *cluster_iter;
	PangoRectangle rect, cluster_rect;
	PangoDirection dir;
	PyObject *ret;
	PyObject *layout_data;
	PyObject *cluster_data;
	PyObject *cluster_range;
	PyObject *cluster_index_data;
	PyObject *cluster_index_range;
	PyObject *glyph_data;

	if (!PyArg_ParseTuple(args, "Oi", &LayoutObj, &len)) {
		return NULL;
	}

	layout = PyCObject_AsVoidPtr(LayoutObj);

	pango_layout_get_size(layout, &w, &h);
	dx = 0.0;
	if (pango_layout_get_alignment(layout) == PANGO_ALIGN_CENTER) {
		dx = -0.5 * ((double) w) / PANGO_SCALE;
	} else if (pango_layout_get_alignment(layout) == PANGO_ALIGN_RIGHT) {
		dx = -1.0 * ((double) w) / PANGO_SCALE;
	}


	ret = PyTuple_New(5);
	layout_data = PyList_New(0);
	cluster_data = PyList_New(0);
	cluster_index_data = PyList_New(0);

	PyTuple_SetItem(ret, 0, layout_data);
	PyTuple_SetItem(ret, 1, cluster_data);
	PyTuple_SetItem(ret, 2, cluster_index_data);

	iter = pango_layout_get_iter(layout);
	cluster_iter = pango_layout_get_iter(layout);

	prev_index = -1;
	rtl_flag = 0;
	ltr_flag = 0;

	dy = ((double) pango_layout_iter_get_baseline(iter)) / PANGO_SCALE;

	for (i = 0; i < len; i++) {
		glyph_data = PyTuple_New(6);

		//Processing EOL

		while (pango_layout_iter_get_baseline(cluster_iter) !=
				pango_layout_iter_get_baseline(iter)) {

			pango_layout_iter_get_char_extents(iter, &rect);

			x = ((double) rect.x) / PANGO_SCALE + dx;
			PyTuple_SetItem(glyph_data, 0, PyFloat_FromDouble(x));

			y = -1.0 * ((double) rect.y) / PANGO_SCALE + dy;
			PyTuple_SetItem(glyph_data, 1, PyFloat_FromDouble(y));

			width = ((double) rect.width) / PANGO_SCALE;
			PyTuple_SetItem(glyph_data, 2, PyFloat_FromDouble(width));

			height = ((double) rect.height) / PANGO_SCALE;
			PyTuple_SetItem(glyph_data, 3, PyFloat_FromDouble(height));

			baseline = -1.0 * ((double) pango_layout_iter_get_baseline(iter))
					/ PANGO_SCALE + dy;
			PyTuple_SetItem(glyph_data, 4, PyFloat_FromDouble(baseline));

			//index processing
			index=pango_layout_iter_get_index(iter);
			prev_index = index;
			PyTuple_SetItem(glyph_data, 5, PyInt_FromLong(index));

			PyList_Append(layout_data, glyph_data);

			pango_layout_iter_next_char(iter);
			i++;
			glyph_data = PyTuple_New(6);
		}

		pango_layout_iter_get_char_extents(iter, &rect);
		pango_layout_iter_get_cluster_extents(cluster_iter, NULL, &cluster_rect);

		//Processing cluster data
		//Layout_data: (x,y,width,height,base_line,byte_index)

		x = ((double) cluster_rect.x) / PANGO_SCALE + dx;
		PyTuple_SetItem(glyph_data, 0, PyFloat_FromDouble(x));

		y = -1.0 * ((double) cluster_rect.y) / PANGO_SCALE + dy;
		PyTuple_SetItem(glyph_data, 1, PyFloat_FromDouble(y));

		width = ((double) cluster_rect.width) / PANGO_SCALE;
		PyTuple_SetItem(glyph_data, 2, PyFloat_FromDouble(width));

		height = ((double) cluster_rect.height) / PANGO_SCALE;
		PyTuple_SetItem(glyph_data, 3, PyFloat_FromDouble(height));

		baseline = -1.0 * ((double) pango_layout_iter_get_baseline(cluster_iter))
				/ PANGO_SCALE + dy;
		PyTuple_SetItem(glyph_data, 4, PyFloat_FromDouble(baseline));

		//index processing
		index=pango_layout_iter_get_index(iter);
		if (prev_index != -1){
			if(index < prev_index){
				rtl_flag=1;
			}else if(index > prev_index){
				ltr_flag=1;
			}
		}
		prev_index = index;
		PyTuple_SetItem(glyph_data, 5, PyInt_FromLong(index));

		PyList_Append(layout_data, glyph_data);

		//Iterating over chars to next cluster

		if(cluster_rect.width > rect.width){
			char_width = rect.width;
			cluster_range = PyTuple_New(2);
			cluster_index_range = PyTuple_New(2);
			PyTuple_SetItem(cluster_range, 0, PyInt_FromLong(i));
			PyTuple_SetItem(cluster_index_range, 0,
					PyInt_FromLong(pango_layout_iter_get_index(iter)));
			while(cluster_rect.width > char_width){
				pango_layout_iter_next_char(iter);
				pango_layout_iter_get_char_extents(iter, &rect);
				char_width = char_width + rect.width;
				i++;
			}
			PyTuple_SetItem(cluster_range, 1, PyInt_FromLong(i + 1));
			PyTuple_SetItem(cluster_index_range, 1,
					PyInt_FromLong(pango_layout_iter_get_index(iter)));
			PyList_Append(cluster_data, cluster_range);
			PyList_Append(cluster_index_data, cluster_index_range);
		}

		pango_layout_iter_next_char(iter);
		pango_layout_iter_next_cluster(cluster_iter);
	}

	pango_layout_iter_free(iter);
	pango_layout_iter_free(cluster_iter);

	if(rtl_flag + ltr_flag == 2){
		PyTuple_SetItem(ret, 3, PyBool_FromLong(1));
	}else{
		PyTuple_SetItem(ret, 3, PyBool_FromLong(0));
	}

	dir = pango_find_base_dir(pango_layout_get_text(layout),-1);
	if(dir == PANGO_DIRECTION_RTL) {
		PyTuple_SetItem(ret, 4, PyBool_FromLong(1));
	} else {
		PyTuple_SetItem(ret, 4, PyBool_FromLong(0));
	}

	return ret;
}
示例#4
0
static PyObject *
pango_GetLayoutCharPos(PyObject *self, PyObject *args) {

	int i, len, w, h;
	double baseline, x, y, width, height, dx, dy;
	void *LayoutObj;
	PangoLayout *layout;
	PangoLayoutIter *iter;
	PangoRectangle rect;
	PyObject *ret;
	PyObject *glyph_data;

	if (!PyArg_ParseTuple(args, "Oi", &LayoutObj, &len)) {
		return NULL;
	}

	layout = PyCObject_AsVoidPtr(LayoutObj);

	pango_layout_get_size(layout, &w, &h);
	dx = 0.0;
	if (pango_layout_get_alignment(layout) == PANGO_ALIGN_CENTER) {
		dx = -0.5 * ((double) w) / PANGO_SCALE;
	} else if (pango_layout_get_alignment(layout) == PANGO_ALIGN_RIGHT) {
		dx = -1.0 * ((double) w) / PANGO_SCALE;
	}


	ret = PyTuple_New(len);
	iter = pango_layout_get_iter(layout);

	dy = ((double) pango_layout_iter_get_baseline(iter)) / PANGO_SCALE;

	for (i = 0; i < len; i++) {
		glyph_data = PyTuple_New(5);
		pango_layout_iter_get_char_extents(iter, &rect);

		x = ((double) rect.x) / PANGO_SCALE + dx;
		PyTuple_SetItem(glyph_data, 0, PyFloat_FromDouble(x));

		y = -1.0 * ((double) rect.y) / PANGO_SCALE + dy;
		PyTuple_SetItem(glyph_data, 1, PyFloat_FromDouble(y));

		width = ((double) rect.width) / PANGO_SCALE;
		PyTuple_SetItem(glyph_data, 2, PyFloat_FromDouble(width));

		height = ((double) rect.height) / PANGO_SCALE;
		PyTuple_SetItem(glyph_data, 3, PyFloat_FromDouble(height));

		baseline = -1.0 * ((double) pango_layout_iter_get_baseline(iter))
				/ PANGO_SCALE + dy;
		PyTuple_SetItem(glyph_data, 4, PyFloat_FromDouble(baseline));

		pango_layout_iter_next_char(iter);

		PyTuple_SetItem(ret, i, glyph_data);
	}

	pango_layout_iter_free(iter);

	return ret;
}
示例#5
0
GpStatus
pango_MeasureString (GpGraphics *graphics, GDIPCONST WCHAR *stringUnicode, int length, GDIPCONST GpFont *font, GDIPCONST RectF *rc,
	GDIPCONST GpStringFormat *format, RectF *boundingBox, int *codepointsFitted, int *linesFilled)
{
	PangoLayout *layout;
	PangoLayoutLine *line;
	PangoRectangle logical;
	PangoLayoutIter *iter;
	int *charsRemoved = NULL;

	cairo_save (graphics->ct);

	layout = gdip_pango_setup_layout (graphics, stringUnicode, length, font, rc, boundingBox, format, &charsRemoved);
	if (!layout) {
		cairo_restore (graphics->ct);
		return OutOfMemory;
	}

	if (codepointsFitted) {
		int charsFitted;
		int lastIndex;
		int y0;
		int y1;
		double min_x;
		double max_x;
		double max_y;
		const char *layoutText;
		if (boundingBox && format && (format->formatFlags & StringFormatFlagsDirectionVertical)) {
			min_x = boundingBox->Y;
			max_x = boundingBox->Y + boundingBox->Height;
			max_y = boundingBox->X + boundingBox->Width;
		} else if (boundingBox) {
			min_x = boundingBox->X;
			max_x = boundingBox->X + boundingBox->Width;
			max_y = boundingBox->Y + boundingBox->Height;
		} else if (format && (format->formatFlags & StringFormatFlagsDirectionVertical)) {
			min_x = rc->Y;
			max_x = rc->Y + rc->Height;
			max_y = rc->X + rc->Width;
		} else {
			min_x = rc->X;
			max_x = rc->X + rc->Width;
			max_y = rc->Y + rc->Height;
		}
		lastIndex = 0;
		iter = pango_layout_get_iter (layout);
		do {
			if (iter == NULL)
				break;
			pango_layout_iter_get_line_yrange (iter, &y0, &y1);
			if (y0 / PANGO_SCALE >= max_y)
				break;
			if (pango_layout_iter_at_last_line (iter)) {
				do {
					pango_layout_iter_get_char_extents (iter, &logical);
					/* check both max and min to catch right-to-left text, also width may be negative */
					if ((logical.x / PANGO_SCALE > max_x || (logical.x + logical.width) / PANGO_SCALE > max_x) || (logical.x / PANGO_SCALE < min_x || (logical.x + logical.width) / PANGO_SCALE < min_x))
						break;
					lastIndex = pango_layout_iter_get_index (iter);
				} while (pango_layout_iter_next_char (iter));
				break;
			} else {
				line = pango_layout_iter_get_line_readonly (iter);
				lastIndex = line->start_index + line->length - 1;
			}
		} while (pango_layout_iter_next_line (iter));
		pango_layout_iter_free (iter);
		layoutText = pango_layout_get_text (layout);
		/* this can happen when the string ends in a newline */
		if (lastIndex >= strlen (layoutText))
			lastIndex = strlen (layoutText) - 1;
		/* Add back in any & characters removed and the final newline characters (if any) */
		charsFitted = g_utf8_strlen (layoutText, lastIndex + 1) + charsRemoved [lastIndex];
		//g_warning("lastIndex: %d\t\tcharsRemoved: %d", lastIndex, charsRemoved[lastIndex]);
		/* safe because of null termination */
		switch (layoutText [lastIndex + 1]) {
			case '\r':
				charsFitted++;
				if (layoutText [lastIndex + 2] == '\n')
					charsFitted++;
				break;
			case '\n':
				charsFitted++;
				break;
		}
		*codepointsFitted = charsFitted;
	}

	GdipFree (charsRemoved);

	if (linesFilled) {
		*linesFilled = pango_layout_get_line_count (layout);
// g_warning ("linesFilled %d", *linesFilled);
	}
// else g_warning ("linesFilled %d", pango_layout_get_line_count (layout));

	g_object_unref (layout);
	cairo_restore (graphics->ct);
	return Ok;
}