bool wxTextMeasure::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths, double scaleX) { if ( !m_layout ) return wxTextMeasureBase::DoGetPartialTextExtents(text, widths, scaleX); // Set layout's text const wxCharBuffer dataUTF8 = wxGTK_CONV_FONT(text, GetFont()); if ( !dataUTF8 ) { // hardly ideal, but what else can we do if conversion failed? wxLogLastError(wxT("GetPartialTextExtents")); return false; } pango_layout_set_text(m_layout, dataUTF8, -1); // Calculate the position of each character based on the widths of // the previous characters // Code borrowed from Scintilla's PlatGTK PangoLayoutIter *iter = pango_layout_get_iter(m_layout); PangoRectangle pos; pango_layout_iter_get_cluster_extents(iter, NULL, &pos); size_t i = 0; while (pango_layout_iter_next_cluster(iter)) { pango_layout_iter_get_cluster_extents(iter, NULL, &pos); int position = PANGO_PIXELS(pos.x); widths[i++] = position; } const size_t len = text.length(); while (i < len) widths[i++] = PANGO_PIXELS(pos.x + pos.width); pango_layout_iter_free(iter); return true; }
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; }
static VALUE layout_iter_next_cluster(VALUE self) { return CBOOL2RVAL(pango_layout_iter_next_cluster(_SELF(self))); }