Browse Source

add fl_draw(int angle, const char* ... functions for rotated text drawing

STR#1840 closed, STR#207 not closed because non-xft functions not implemented 

drawing of N Utf8 characters need correction for rotated and not rotated fl_draw functions not solved!


git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6779 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
pull/49/head
yuri 16 years ago
parent
commit
f13defde28
  1. 13
      FL/fl_draw.H
  2. 2
      TODO.utf8
  3. 2
      src/Fl_Font.H
  4. 4
      src/fl_font.cxx
  5. 23
      src/fl_font_mac.cxx
  6. 49
      src/fl_font_win32.cxx
  7. 5
      src/fl_font_x.cxx
  8. 38
      src/fl_font_xft.cxx
  9. 4
      test/Makefile

13
FL/fl_draw.H

@ -283,10 +283,23 @@ FL_EXPORT const char *fl_local_to_mac_roman(const char *t, int n=-1); @@ -283,10 +283,23 @@ FL_EXPORT const char *fl_local_to_mac_roman(const char *t, int n=-1);
to control characters.
*/
FL_EXPORT void fl_draw(const char* str, int x, int y);
/**
Draws a nul-terminated string starting at the given location and
rotating \p angle degrees counterclockwise.
This version of fl_draw provides direct access to the text drawing
function of the underlying OS and suported for Xft, Win32 and MacOS
fltk subset.
*/
FL_EXPORT void fl_draw(int angle,const char* str, int x, int y);
/**
Draws an array of \p n characters starting at the given location.
*/
FL_EXPORT void fl_draw(const char* str, int n, int x, int y);
/**
Draws an array of \p n characters starting at the given location,
rotating \p angle degrees counterclockwise.
*/
FL_EXPORT void fl_draw(int angle,const char* str, int n, int x, int y);
/**
Draws an array of \p n characters right to left starting at given location.
*/

2
TODO.utf8

@ -28,6 +28,8 @@ Bugs that have to be fixed before an RC @@ -28,6 +28,8 @@ Bugs that have to be fixed before an RC
* Make consistent use of fltk's utf8 functions for e.g. all string handling (see Ian's post on 03/25/09)
* fix fl_draw(cons char*, int n, int x, int y) and related for drawing realy n unicode characters
* (add your items here)

2
src/Fl_Font.H

@ -56,6 +56,7 @@ public: @@ -56,6 +56,7 @@ public:
HFONT fid;
int *width[64];
TEXTMETRIC metr;
int angle;
FL_EXPORT Fl_Font_Descriptor(const char* fontname, Fl_Fontsize size);
# elif defined(__APPLE_QD__)
FL_EXPORT Fl_Font_Descriptor(const char* fontname, Fl_Fontsize size);
@ -76,6 +77,7 @@ public: @@ -76,6 +77,7 @@ public:
XftFont* font;
const char* encoding;
Fl_Fontsize size;
int angle;
FL_EXPORT Fl_Font_Descriptor(const char* xfontname);
# else
XUtf8FontStruct* font; // X UTF-8 font information

4
src/fl_font.cxx

@ -68,6 +68,10 @@ void fl_draw(const char* str, int x, int y) { @@ -68,6 +68,10 @@ void fl_draw(const char* str, int x, int y) {
fl_draw(str, strlen(str), x, y);
}
void fl_draw(int angle, const char* str, int x, int y) {
fl_draw(angle, str, strlen(str), x, y);//must be fixed!
}
void fl_text_extents(const char *c, int &dx, int &dy, int &w, int &h) {
if (c) fl_text_extents(c, strlen(c), dx, dy, w, h);
else {

23
src/fl_font_mac.cxx

@ -339,6 +339,29 @@ void fl_draw(const char *str, int n, float x, float y) { @@ -339,6 +339,29 @@ void fl_draw(const char *str, int n, float x, float y) {
err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x), FloatToFixed(y));
}
void fl_draw(int angle, const char *str, int n, int x, int y) {
OSStatus err;
// convert to UTF-16 first
UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n);
// avoid a crash if no font has been selected by user yet !
check_default_font();
// now collect our ATSU resources
ATSUTextLayout layout = fl_fontsize->layout;
Fixed ang = IntToFixed(-angle);
ByteCount iSize[] = {sizeof(Fixed), sizeof(CGContextRef)};
ATSUAttributeTag iTag[] = {kATSULineRotationTag, kATSUCGContextTag};
ATSUAttributeValuePtr aAttr[] = { &ang, &fl_gc};
ATSUSetLayoutControls(layout, 2, iTag, iSize, aAttr);
err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n);
err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x), FloatToFixed(y));
//restore layout baseline
ang = IntToFixed(0);
ATSUSetLayoutControls(layout, 2, iTag, iSize, aAttr);
}
void fl_rtl_draw(const char* c, int n, int x, int y) {
// I guess with ATSU the thing to do is force the layout mode to RTL and let ATSU draw the text...
double offs = fl_width(c, n);

49
src/fl_font_win32.cxx

@ -24,6 +24,8 @@ @@ -24,6 +24,8 @@
//
// http://www.fltk.org/str.php
//
static int fl_angle_ = 0;
#ifndef FL_DOXYGEN
Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize size) {
int weight = FW_NORMAL;
@ -38,8 +40,8 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize size) { @@ -38,8 +40,8 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize size) {
fid = CreateFont(
-size, // negative makes it use "char size"
0, // logical average character width
0, // angle of escapement
0, // base-line orientation angle
fl_angle_*10, // angle of escapement
fl_angle_*10, // base-line orientation angle
weight,
italic,
FALSE, // underline attribute flag
@ -51,6 +53,7 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize size) { @@ -51,6 +53,7 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize size) {
DEFAULT_PITCH, // pitch and family
name // pointer to typeface name string
);
angle = fl_angle_;
if (!fl_gc) fl_GetDC(0);
SelectObject(fl_gc, fid);
GetTextMetrics(fl_gc, &metr);
@ -111,12 +114,12 @@ static Fl_Fontdesc built_in_table[] = { @@ -111,12 +114,12 @@ static Fl_Fontdesc built_in_table[] = {
Fl_Fontdesc* fl_fonts = built_in_table;
static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) {
static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size, int angle) {
Fl_Fontdesc* s = fl_fonts+fnum;
if (!s->name) s = fl_fonts; // use 0 if fnum undefined
Fl_Font_Descriptor* f;
for (f = s->first; f; f = f->next)
if (f->minsize <= size && f->maxsize >= size) return f;
if (f->minsize <= size && f->maxsize >= size && f->angle == angle) return f;
f = new Fl_Font_Descriptor(s->name, size);
f->next = s->first;
s->first = f;
@ -130,14 +133,18 @@ Fl_Font fl_font_ = 0; @@ -130,14 +133,18 @@ Fl_Font fl_font_ = 0;
Fl_Fontsize fl_size_ = 0;
//static HDC font_gc;
void fl_font(Fl_Font fnum, Fl_Fontsize size) {
void fl_font(Fl_Font fnum, Fl_Fontsize size, int angle) {
if (fnum==-1) { // just make sure that we will load a new font next time
fl_font_ = 0; fl_size_ = 0;
fl_font_ = 0; fl_size_ = 0; fl_angle_ = 0;
return;
}
if (fnum == fl_font_ && size == fl_size_) return;
fl_font_ = fnum; fl_size_ = size;
fl_fontsize = find(fnum, size);
if (fnum == fl_font_ && size == fl_size_ && angle == fl_angle_) return;
fl_font_ = fnum; fl_size_ = size; fl_angle_ = angle;
fl_fontsize = find(fnum, size, angle);
}
void fl_font(Fl_Font fnum, Fl_Fontsize size) {
fl_font(fnum, size, 0);
}
int fl_height() {
@ -335,6 +342,30 @@ void fl_draw(const char* str, int n, int x, int y) { @@ -335,6 +342,30 @@ void fl_draw(const char* str, int n, int x, int y) {
SetTextColor(fl_gc, oldColor);
}
void fl_draw(int angle, const char* str, int n, int x, int y) {
fl_font(fl_font_, fl_size_, angle);
// fl_draw(str, n, (int)x, (int)y);
int i = 0, i2=0;
char *end = (char *)&str[n];
COLORREF oldColor = SetTextColor(fl_gc, fl_RGB());
SelectObject(fl_gc, fl_fontsize->fid);
//unsigned short ucs[n]; //only GCC, but not MSVC
unsigned short* ucs = new unsigned short[n];
while (i < n) {
unsigned int u;
int l;
u = fl_utf8decode((const char*)(str + i), end, &l);
ucs[i2] = u;
if (l < 1) l = 1;
i += l;
++i2;
}
TextOutW(fl_gc, x, y, (WCHAR*)ucs, i2);
delete[] ucs;
SetTextColor(fl_gc, oldColor);
fl_font(fl_font_, fl_size_);
}
void fl_rtl_draw(const char* c, int n, int x, int y) {
int wn;
int i = 0;

5
src/fl_font_x.cxx

@ -319,7 +319,10 @@ void fl_draw(const char* c, int n, int x, int y) { @@ -319,7 +319,10 @@ void fl_draw(const char* c, int n, int x, int y) {
// XDrawString(fl_display, fl_window, fl_gc, x, y, c, n);
XUtf8DrawString(fl_display, fl_window, fl_xfont, fl_gc, x, y, c, n);
}
void fl_draw(int angle, const char *str, int n, int x, int y) {
fprintf(stderr,"ROTATING TEXT NOT IMPLIMENTED\n");
fl_draw(str, n, (int)x, (int)y);
}
//void fl_draw(const char* str, int n, float x, float y) {
// fl_draw(str, n, (int)x, (int)y);
//}

38
src/fl_font_xft.cxx

@ -65,6 +65,8 @@ @@ -65,6 +65,8 @@
#include <X11/Xft/Xft.h>
#include <math.h>
// The predefined fonts that FLTK has:
static Fl_Fontdesc built_in_table[] = {
{" sans"},
@ -91,6 +93,7 @@ Fl_Fontdesc* fl_fonts = built_in_table; @@ -91,6 +93,7 @@ Fl_Fontdesc* fl_fonts = built_in_table;
Fl_Font fl_font_ = 0;
Fl_Fontsize fl_size_ = 0;
int fl_angle_ = 0; // internal for rotating text support
//XFontStruct* fl_xfont = 0;
XUtf8FontStruct* fl_xfont = 0;
void *fl_xftfont = 0;
@ -98,21 +101,23 @@ void *fl_xftfont = 0; @@ -98,21 +101,23 @@ void *fl_xftfont = 0;
const char* fl_encoding_ = "iso10646-1";
Fl_Font_Descriptor* fl_fontsize = 0;
void fl_font(Fl_Font fnum, Fl_Fontsize size) {
void fl_font(Fl_Font fnum, Fl_Fontsize size, int angle) {
if (fnum==-1) { // special case to stop font caching
fl_font_ = 0; fl_size_ = 0;
fl_font_ = 0; fl_size_ = 0; fl_angle_ = 0;
return;
}
if (fnum == fl_font_ && size == fl_size_
if (fnum == fl_font_ && size == fl_size_ && angle == fl_angle_
&& fl_fontsize)
// && !strcasecmp(fl_fontsize->encoding, fl_encoding_))
return;
fl_font_ = fnum; fl_size_ = size;
fl_font_ = fnum; fl_size_ = size; fl_angle_ = angle;
Fl_Fontdesc *font = fl_fonts + fnum;
Fl_Font_Descriptor* f;
// search the fontsizes we have generated already
for (f = font->first; f; f = f->next) {
if (f->size == size)// && !strcasecmp(f->encoding, fl_encoding_))
if (f->size == size && f->angle == angle)// && !strcasecmp(f->encoding, fl_encoding_))
break;
}
if (!f) {
@ -127,7 +132,11 @@ void fl_font(Fl_Font fnum, Fl_Fontsize size) { @@ -127,7 +132,11 @@ void fl_font(Fl_Font fnum, Fl_Fontsize size) {
fl_xftfont = (void*)f->font;
}
static XftFont* fontopen(const char* name, bool core) {
void fl_font(Fl_Font fnum, Fl_Fontsize size) {
fl_font(fnum,size,0);
}
static XftFont* fontopen(const char* name, bool core, int angle) {
// Check: does it look like we have been passed an old-school XLFD fontname?
bool is_xlfd = false;
int hyphen_count = 0;
@ -207,6 +216,14 @@ static XftFont* fontopen(const char* name, bool core) { @@ -207,6 +216,14 @@ static XftFont* fontopen(const char* name, bool core) {
XftPatternAddDouble (fnt_pat, XFT_PIXEL_SIZE, (double)fl_size_);
XftPatternAddString (fnt_pat, XFT_ENCODING, fl_encoding_);
// rotate font if fl_angle_!=0
if (fl_angle_ !=0) {
XftMatrix m;
XftMatrixInit(&m);
XftMatrixRotate(&m,cos(M_PI*fl_angle_/180.),sin(M_PI*fl_angle_/180.));
XftPatternAddMatrix (fnt_pat, XFT_MATRIX,&m);
}
if (core) {
XftPatternAddBool(fnt_pat, XFT_CORE, FcTrue);
XftPatternAddBool(fnt_pat, XFT_RENDER, FcFalse);
@ -295,10 +312,11 @@ puts("Font Opened"); fflush(stdout); @@ -295,10 +312,11 @@ puts("Font Opened"); fflush(stdout);
Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name) {
// encoding = fl_encoding_;
size = fl_size_;
angle = fl_angle_;
#if HAVE_GL
listbase = 0;
#endif // HAVE_GL
font = fontopen(name, false);
font = fontopen(name, false, angle);
}
Fl_Font_Descriptor::~Fl_Font_Descriptor() {
@ -514,6 +532,12 @@ void fl_draw(const char *str, int n, int x, int y) { @@ -514,6 +532,12 @@ void fl_draw(const char *str, int n, int x, int y) {
XftDrawStringUtf8(draw, &color, current_font, x, y, (XftChar8 *)str, n);
}
void fl_draw(int angle, const char *str, int n, int x, int y) {
fl_font(fl_font_, fl_size_, angle);
fl_draw(str, n, (int)x, (int)y);
fl_font(fl_font_, fl_size_);
}
void fl_draw(const char* str, int n, float x, float y) {
fl_draw(str, n, (int)x, (int)y);
}

4
test/Makefile

@ -84,6 +84,7 @@ CPPFILES =\ @@ -84,6 +84,7 @@ CPPFILES =\
radio.cxx \
resizebox.cxx \
resize.cxx \
rotated_text.cxx \
scroll.cxx \
shape.cxx \
subwindow.cxx \
@ -146,6 +147,7 @@ ALL = \ @@ -146,6 +147,7 @@ ALL = \
radio$(EXEEXT) \
resize$(EXEEXT) \
resizebox$(EXEEXT) \
rotated_text$(EXEEXT) \
scroll$(EXEEXT) \
subwindow$(EXEEXT) \
sudoku$(EXEEXT) \
@ -398,6 +400,8 @@ resize.cxx: resize.fl ../fluid/fluid$(EXEEXT) @@ -398,6 +400,8 @@ resize.cxx: resize.fl ../fluid/fluid$(EXEEXT)
resizebox$(EXEEXT): resizebox.o
rotated_text$(EXEEXT): rotated_text.o
scroll$(EXEEXT): scroll.o
subwindow$(EXEEXT): subwindow.o

Loading…
Cancel
Save