add a length argument to the internal GetTextExtent, so that the implementation of string snips can avoid a temporary mutation (which turns out to be dangerous, unsurprisingly, when reflowing text for a PostScript output)

svn: r4901
This commit is contained in:
Matthew Flatt 2006-11-21 01:37:37 +00:00
parent c537bfb8ac
commit d0a37a636c
25 changed files with 74 additions and 66 deletions

View File

@ -3539,19 +3539,23 @@ long wxMediaEdit::_FindPositionInSnip(wxDC *dc, double X, double Y,
while (1) {
double dl, dr;
if ((dl = snip->PartialOffset(dc, X, Y, offset + i)) > x)
dl = snip->PartialOffset(dc, X, Y, offset + i);
if (dl > x)
range = i;
else if ((dr = snip->PartialOffset(dc, X, Y, offset + i + 1)) <= x) {
offset += i;
range -= i;
} else {
if (how_close) {
if (dr - x < x - dl)
*how_close = dr - x;
else
*how_close = dl - x;
else {
dr = snip->PartialOffset(dc, X, Y, offset + i + 1);
if (dr <= x) {
offset += i;
range -= i;
} else {
if (how_close) {
if (dr - x < x - dl)
*how_close = dr - x;
else
*how_close = dl - x;
}
break;
}
break;
}
i = range / 2;

View File

@ -592,14 +592,10 @@ void wxTextSnip::SizeCacheInvalid(void)
void wxTextSnip::GetTextExtent(wxDC *dc, int count, double *wo)
{
wxchar save;
double _w, h;
wxFont *font;
int i;
save = buffer[dtext + count];
buffer[dtext + count] = 0;
for (i = count; i--; ) {
wxchar c = buffer[dtext + i];
if (!c || (c == NON_BREAKING_SPACE))
@ -612,7 +608,7 @@ void wxTextSnip::GetTextExtent(wxDC *dc, int count, double *wo)
#endif
if (i < 0) {
dc->GetTextExtent((char *)buffer, &_w, &h, NULL, NULL, font, FALSE, TRUE, dtext);
dc->GetTextExtent((char *)buffer, &_w, &h, NULL, NULL, font, FALSE, TRUE, dtext, count);
} else {
/* text includes null chars */
double ex_w;
@ -628,10 +624,7 @@ void wxTextSnip::GetTextExtent(wxDC *dc, int count, double *wo)
if (!buffer[dtext + i] || (buffer[dtext + i] == NON_BREAKING_SPACE) || (i == count)) {
if (i > start) {
double piece_w, h;
wxchar save = buffer[dtext + i];
buffer[dtext + i] = 0;
dc->GetTextExtent((char *)buffer, &piece_w, &h, NULL, NULL, NULL, FALSE, TRUE, dtext + start);
buffer[dtext + i] = save;
dc->GetTextExtent((char *)buffer, &piece_w, &h, NULL, NULL, NULL, FALSE, TRUE, dtext + start, i - start);
_w += piece_w;
}
if (i < count) {
@ -641,8 +634,6 @@ void wxTextSnip::GetTextExtent(wxDC *dc, int count, double *wo)
}
}
}
buffer[dtext + count] = save;
*wo = _w;
}

View File

@ -1342,7 +1342,7 @@ void wxPostScriptDrawText(Scheme_Object *f, const char *fontname,
}
extern void wxPostScriptGetTextExtent(const char *fontname,
const char *text, int dt, Bool combine, int use16,
const char *text, int dt, int slen, Bool combine, int use16,
double font_size,
double *x, double *y, double *descent, double *topSpace,
int sym_map)
@ -1354,9 +1354,9 @@ extern void wxPostScriptGetTextExtent(const char *fontname,
a[0] = v;
a[1] = scheme_make_double(font_size);
if (use16)
v = scheme_make_sized_offset_char_string((mzchar *)text, dt, -1, 1);
v = scheme_make_sized_offset_char_string((mzchar *)text, dt, slen, 1);
else
v = scheme_make_sized_offset_utf8_string((char *)text, dt, -1);
v = scheme_make_sized_offset_utf8_string((char *)text, dt, slen);
a[2] = v;
a[3] = (combine ? scheme_true : scheme_false);
a[4] = (sym_map ? scheme_true : scheme_false);

View File

@ -71,7 +71,7 @@ extern void wxPostScriptDrawText(Scheme_Object *f, const char *fontname,
const char *text, int dt, Bool combine, int use16,
double font_size, int symbol_map);
extern void wxPostScriptGetTextExtent(const char *fontname,
const char *text, int dt, Bool combine, int use16,
const char *text, int dt, int len, Bool combine, int use16,
double font_size,
double *x, double *y, double *descent, double *topSpace,
int symbol_map);
@ -1963,7 +1963,7 @@ double wxPostScriptDC::GetCharWidth (void)
void wxPostScriptDC::GetTextExtent (const char *string, double *x, double *y,
double *descent, double *topSpace, wxFont *theFont,
Bool combine, Bool use16, int dt)
Bool combine, Bool use16, int dt, int slen)
{
wxFont *fontToUse = theFont;
int family;
@ -1987,7 +1987,7 @@ void wxPostScriptDC::GetTextExtent (const char *string, double *x, double *y,
sym_map = fontToUse->GetFamily() == wxSYMBOL;
wxPostScriptGetTextExtent(name, string, dt, combine, use16, size,
wxPostScriptGetTextExtent(name, string, dt, slen, combine, use16, size,
x, y, descent, topSpace, sym_map);
}

View File

@ -129,7 +129,7 @@ class wxPostScriptDC: public wxDC
void GetTextExtent(const char *string, double *x, double *y,
double *descent = NULL, double *externalLeading = NULL,
wxFont *theFont = NULL,
Bool combine = FALSE, Bool use16 = FALSE, int dt = 0);
Bool combine = FALSE, Bool use16 = FALSE, int dt = 0, int slen = -1);
void SetMapMode(int mode);
void SetUserScale(double x, double y);
double DeviceToLogicalX(int x);

View File

@ -159,7 +159,7 @@ class wxbDC: public wxObject
virtual void GetTextExtent(const char* string, double* x, double* y, double* descent = NULL,
double* externalLeading = NULL, wxFont* the_font = NULL,
Bool combine=FALSE, Bool use16=FALSE,
int d = 0) = 0;
int d = 0, int len = -1) = 0;
inline virtual Bool Ok(void) {return ok;};
virtual void SetMapMode(int mode) = 0;
inline virtual int GetMapMode(void) {return mapping_mode;};

View File

@ -122,7 +122,7 @@ class wxCanvasDC: public wxbCanvasDC
virtual void GetTextExtent(const char* string, double* x, double* y, double* descent = NULL,
double* externalLeading = NULL, wxFont* the_font = NULL,
Bool combine = FALSE, Bool use16 = FALSE,
int d = 0);
int d = 0, int len = -1);
Bool StartDoc(char* message);
void EndDoc(void);
void StartPage(void);

View File

@ -46,7 +46,7 @@ class wxFont: public wxbFont
double GetCharHeight(double scale_x = 1.0, double scale_y = 1.0);
double GetCharWidth(double scale_x = 1.0, double scale_y = 1.0);
void GetTextExtent(char* string, int delta, double* x, double* y,
void GetTextExtent(char* string, int delta, int len, double* x, double* y,
double* descent, double* externalLeading,
Bool qd_spacing = TRUE, Bool use16 = FALSE,
double scale_x = 1.0, double scale_y = 1.0);

View File

@ -43,7 +43,7 @@ wxLabelArea::wxLabelArea
double fLabelWidth, fLabelHeight, fDescent, fExternalLeading;
labelText = cLabelText->GetLabel();
labelFont->GetTextExtent(labelText, 0, &fLabelWidth, &fLabelHeight,
labelFont->GetTextExtent(labelText, 0, -1, &fLabelWidth, &fLabelHeight,
&fDescent, &fExternalLeading, TRUE);
labelWidth = (int)fLabelWidth;
labelHeight = (int)fLabelHeight;

View File

@ -1325,7 +1325,7 @@ static void draw_tab_label(const Rect *bounds,
char *str = ((tab_info *)ti)->str;
double w, h, d, dy, dx;
font->GetTextExtent(str, 0, &w, &h, &d, NULL, FALSE);
font->GetTextExtent(str, 0, -1, &w, &h, &d, NULL, FALSE);
dy = ((bounds->bottom - bounds->top - 3) - (h - d)) / 2;
dx = ((bounds->right - bounds->left) - w) / 2;

View File

@ -380,7 +380,7 @@ double wxCanvasDC::GetCharWidth(void)
//-----------------------------------------------------------------------------
void wxCanvasDC::GetTextExtent(const char* string, double* x, double* y, double* descent,
double* internalLeading, wxFont* the_font,
Bool combine, Bool ucs4, int d)
Bool combine, Bool ucs4, int d, int slen)
{
double x2, y2, descent2, externalLeading2;
@ -388,11 +388,11 @@ void wxCanvasDC::GetTextExtent(const char* string, double* x, double* y, double*
in font selection. */
if (the_font)
the_font->GetTextExtent((char *)string, d, &x2, &y2, &descent2, &externalLeading2,
the_font->GetTextExtent((char *)string, d, slen, &x2, &y2, &descent2, &externalLeading2,
!combine, ucs4,
user_scale_x, user_scale_y);
else if (font)
font->GetTextExtent((char *)string, d, &x2, &y2, &descent2, &externalLeading2,
font->GetTextExtent((char *)string, d, slen, &x2, &y2, &descent2, &externalLeading2,
!combine, ucs4,
user_scale_x, user_scale_y);
else {

View File

@ -65,7 +65,7 @@ wxGroupBox::wxGroupBox(wxPanel *panel, char *label, int style, wxFont *_font)
double x, y;
wxFont *bold;
bold = new WXGC_PTRS wxFont(font->GetPointSize(), font->GetFontId(), font->GetStyle(), wxBOLD, 0);
bold->GetTextExtent(wxItemStripLabel(label), 0, &x, &y, NULL, NULL, TRUE, FALSE);
bold->GetTextExtent(wxItemStripLabel(label), 0, -1, &x, &y, NULL, NULL, TRUE, FALSE);
cWindowWidth = (int)x + GBOX_EXTRA_H_SPACE;
cWindowHeight = (int)y + GBOX_EXTRA_SPACE;
}

View File

@ -356,12 +356,12 @@ double wxFont::GetCharWidth(double scale_x, double scale_y)
}
//-----------------------------------------------------------------------------
void wxFont::GetTextExtent(char* string, int delta, double* x, double* y,
void wxFont::GetTextExtent(char* string, int delta, int slen, double* x, double* y,
double* descent, double* externalLeading,
Bool qd_spacing, Bool ucs4,
double scale_x, double scale_y)
{
wxGetUnicodeTextWidth(string, delta, -1,
wxGetUnicodeTextWidth(string, delta, slen,
GetMacFontNum(), point_size, GetMacFontStyle(),
ucs4, scale_y,
x, y, descent, externalLeading,

View File

@ -170,7 +170,7 @@ void wxGetBestControlRect(ControlRef c, Rect *r, SInt16 *offset,
if (label && (size < 13)) {
/* GetBestControlRect makes things too wide */
double x, y;
font->GetTextExtent(label, 0, &x, &y, NULL, NULL);
font->GetTextExtent(label, 0, -1, &x, &y, NULL, NULL);
if (r->right - r->left > x + width_pad)
r->right = r->left + (short)x + (short)width_pad;
}

View File

@ -234,7 +234,7 @@ void wxMessage::CreateWxMessage(char* label, wxFont* theFont) // common construc
clientWidth = 20;
clientHeight = 14;
if (font) {
font->GetTextExtent(cMessage, 0, &clientWidth, &clientHeight, NULL, NULL, TRUE);
font->GetTextExtent(cMessage, 0, -1, &clientWidth, &clientHeight, NULL, NULL, TRUE);
if (font->GetStyle() != wxNORMAL)
clientWidth += 5; //cjc - try hello.cc italic labels are truncated
}

View File

@ -245,7 +245,7 @@ void wxSlider::Paint(void)
if (font && (font != wxNORMAL_FONT)) {
double w, h, d, dx;
font->GetTextExtent(t, 0, &w, &h, &d, NULL, FALSE);
font->GetTextExtent(t, 0, -1, &w, &h, &d, NULL, FALSE);
dx = ((r.right - r.left) - w) / 2;
MoveTo((short)floor(r.left + dx), (short)floor(r.top + (h - d)));

View File

@ -110,7 +110,7 @@ wxTabChoice::wxTabChoice(wxPanel *panel, wxFunction function, char *label,
cWindowWidth = TAB_TITLE_SPACE + TAB_BASE_SIDE_SPACE;
for (i = 0; i < N; i++) {
double x, y;
font->GetTextExtent(wxItemStripLabel(Choices[i]), 0, &x, &y, NULL, NULL, TRUE);
font->GetTextExtent(wxItemStripLabel(Choices[i]), 0, -1, &x, &y, NULL, NULL, TRUE);
cWindowWidth += TAB_TITLE_SPACE + (int)x;
}
padTop = TAB_TOP_SPACE;

View File

@ -1666,9 +1666,9 @@ void wxWindow::GetTextExtent(const char* string, double* x, double* y, double* d
double* externalLeading, wxFont* the_font, Bool use16)
{
if (the_font)
the_font->GetTextExtent((char *)string, 0, x, y, descent, externalLeading, TRUE, use16);
the_font->GetTextExtent((char *)string, 0, -1, x, y, descent, externalLeading, TRUE, use16);
else if (font)
font->GetTextExtent((char *)string, 0, x, y, descent, externalLeading, TRUE, use16);
font->GetTextExtent((char *)string, 0, -1, x, y, descent, externalLeading, TRUE, use16);
else {
*x = -1;
*y = -1;

View File

@ -149,7 +149,7 @@ class wxbDC: public wxObject
double *externalLeading = NULL,
wxFont *theFont = NULL,
Bool combine = FALSE, Bool use16bit = FALSE,
int d = 0) = 0;
int d = 0, int len = -1) = 0;
inline virtual Bool Ok(void) {return ok;};
virtual Bool CanGetTextExtent(void) = 0;

View File

@ -122,7 +122,7 @@ class wxDC: public wxbDC
void GetTextExtent(const char *string, double *x, double *y,
double *descent = NULL, double *externalLeading = NULL,
wxFont *theFont = NULL,
Bool combine = FALSE, Bool use16bit = FALSE, int d = 0);
Bool combine = FALSE, Bool use16bit = FALSE, int d = 0, int len = -1);
void GetSize(double *width, double *height);
void GetSizeMM(double *width, double *height);
Bool StartDoc(char *message);

View File

@ -1616,10 +1616,13 @@ wchar_t *convert_to_drawable_format(const char *text, int d, int ucs4, long *_ul
wchar_t *unicode;
int theStrlen;
if (ucs4) {
theStrlen = ucs4_strlen((const unsigned int *)text XFORM_OK_PLUS d);
} else {
theStrlen = strlen(text XFORM_OK_PLUS d);
theStrlen = *_ulen;
if (theStrlen < 0) {
if (ucs4) {
theStrlen = ucs4_strlen((const unsigned int *)text XFORM_OK_PLUS d);
} else {
theStrlen = strlen(text XFORM_OK_PLUS d);
}
}
if (ucs4) {
@ -1817,7 +1820,7 @@ void wxDC::DrawText(const char *text, double x, double y, Bool combine, Bool ucs
DWORD old_background;
double w, h, ws, hs, ow, oh;
wchar_t *ustring;
long len, alen;
long len = -1, alen;
double oox, ooy;
int fam, reset = 0;
wxFont *theFont;
@ -2139,12 +2142,12 @@ double wxDC::GetCharWidth(void)
void wxDC::GetTextExtent(const char *string, double *x, double *y,
double *descent, double *topSpace,
wxFont *theFont, Bool combine, Bool ucs4, int d)
wxFont *theFont, Bool combine, Bool ucs4, int d, int slen)
{
wxFont *oldFont = NULL;
HDC dc;
TEXTMETRIC tm;
long len, alen;
long len = slen, alen;
double tx, ty, ow, oh;
wchar_t *ustring;
int once = 1, fam, reset = 0;

View File

@ -106,7 +106,8 @@ public:
virtual void GetTextExtent(const char *s, double *w, double *h,
double *descent = 0, double *ext_leading = 0,
wxFont *font=NULL,
Bool combine=FALSE, Bool use16bit=FALSE, int dt=0) = 0;
Bool combine=FALSE, Bool use16bit=FALSE, int dt=0,
int len = -1) = 0;
virtual void SetBackground(wxColour *c) = 0;
virtual void SetBrush(wxBrush *brush) = 0;
virtual void SetClippingRect(double x, double y, double w, double h) = 0;

View File

@ -2151,11 +2151,14 @@ static unsigned int *convert_to_drawable_format(const char *s, int ds, long *_ul
int isUnicode, int non_xft)
{
unsigned int *us;
long ulen;
long ulen = *_ulen;
if (isUnicode) {
us = (unsigned int *)s;
for (ulen = ds; us[ulen]; ulen++) {
if (ulen < 0) {
ulen = 0;
for (ulen = ds; us[ulen]; ulen++) {
}
}
ulen -= ds;
if (ds) {
@ -2168,7 +2171,10 @@ static unsigned int *convert_to_drawable_format(const char *s, int ds, long *_ul
} else {
int length;
length = strlen(s XFORM_OK_PLUS ds);
if (ulen < 0)
length = strlen(s XFORM_OK_PLUS ds);
else
length = ulen;
ulen = scheme_utf8_decode((const unsigned char *)s, ds, ds + length, NULL, 0, -1, NULL, 0, '?');
if (ulen <= bufsize)
@ -2287,12 +2293,13 @@ void wxWindowDC::DrawText(char *orig_text, double x, double y,
{
double tw, th, td, ts;
GetTextExtent(orig_text, &tw, &th, &td, &ts, current_font, combine, isUnicode, dt);
GetTextExtent(orig_text, &tw, &th, &td, &ts, current_font, combine, isUnicode, dt, -1);
cx = (tw * e_scale_x);
cy = (th * e_scale_y);
ascent = (int)((th - td) * e_scale_y);
}
textlen = -1;
text = convert_to_drawable_format(orig_text, dt, &textlen, cvt_buf, WX_CVT_BUF_SIZE,
isUnicode, WX_XFT_ONLY(!xfontinfo));
dt = 0;
@ -2515,7 +2522,7 @@ double wxWindowDC::GetCharWidth(void)
void wxGetTextExtent(Display *dpy, double scale_x, double scale_y,
const char *orig_s, double *_w, double *_h, double *_descent,
double *_topspace, wxFont *font_to_use,
Bool combine, Bool isUnicode, int dt)
Bool combine, Bool isUnicode, int dt, int len)
{
int ascent, descent, space = 0;
long textlen;
@ -2534,6 +2541,7 @@ void wxGetTextExtent(Display *dpy, double scale_x, double scale_y,
#endif
fontinfo = (XFontStruct*)font_to_use->GetInternalFont(scale_x, scale_y);
textlen = len;
s = convert_to_drawable_format(orig_s, dt, &textlen, cvt_buf, WX_CVT_BUF_SIZE,
isUnicode, WX_XFT_ONLY(!xfontinfo));
dt = 0;
@ -2629,7 +2637,7 @@ void wxGetTextExtent(Display *dpy, double scale_x, double scale_y,
void wxWindowDC::GetTextExtent(const char *orig_s, double *_w, double *_h, double *_descent,
double *_topspace, wxFont *_font,
Bool combine, Bool isUnicode, int dt)
Bool combine, Bool isUnicode, int dt, int len)
{
wxFont *font_to_use;
double v;
@ -2649,7 +2657,7 @@ void wxWindowDC::GetTextExtent(const char *orig_s, double *_w, double *_h, doubl
wxGetTextExtent(DPY, scale_x, scale_y,
orig_s, _w, _h, _descent, _topspace,
font_to_use, combine, isUnicode, dt);
font_to_use, combine, isUnicode, dt, len);
if (_w) {
v = XDEV2LOGREL((int)*_w);

View File

@ -147,7 +147,8 @@ public:
double GetCharWidth(void);
void GetTextExtent(const char *s, double *w, double *h, double *descent = 0,
double *ext_leading = 0, wxFont *font=NULL,
Bool combine=FALSE, Bool use16bit=FALSE, int dt=0);
Bool combine=FALSE, Bool use16bit=FALSE, int dt=0,
int len=-1);
void SetBackground(wxColour *c);
void SetBrush(wxBrush *brush);
void ResetBrush(wxBrush *brush);
@ -264,7 +265,7 @@ public:
void wxGetTextExtent(Display *dpy, double scale_x, double scale_y,
const char *orig_s, double *_w, double *_h, double *_descent,
double *_topspace, wxFont *font_to_use,
Bool combine, Bool isUnicode, int dt);
Bool combine, Bool isUnicode, int dt, int len);
#endif
#endif // WindowDC_hh

View File

@ -2227,7 +2227,7 @@ void wxWindow::GetTextExtent(const char *s, double *w, double *h, double *descen
wxGetTextExtent(wxAPP_DISPLAY, 1.0, 1.0,
s, w, h, descent, ext_leading, theFont,
1, use16bit, 0);
1, use16bit, 0, -1);
}