summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryuri <yuri>2009-04-24 09:28:30 +0000
committeryuri <yuri>2009-04-24 09:28:30 +0000
commitf13defde281dbd383dbc21488154a109dff50b40 (patch)
treed2b2725fc4c8054797cc3018abd5e1baef489e2d
parentca3984892fecd1e2784e65226b2c44d2eba0671b (diff)
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
-rw-r--r--FL/fl_draw.H13
-rw-r--r--TODO.utf82
-rw-r--r--src/Fl_Font.H2
-rw-r--r--src/fl_font.cxx4
-rw-r--r--src/fl_font_mac.cxx23
-rw-r--r--src/fl_font_win32.cxx49
-rw-r--r--src/fl_font_x.cxx5
-rw-r--r--src/fl_font_xft.cxx38
-rw-r--r--test/Makefile4
9 files changed, 123 insertions, 17 deletions
diff --git a/FL/fl_draw.H b/FL/fl_draw.H
index f0af55781..f10bcaa7c 100644
--- a/FL/fl_draw.H
+++ b/FL/fl_draw.H
@@ -284,10 +284,23 @@ FL_EXPORT const char *fl_local_to_mac_roman(const char *t, int n=-1);
*/
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.
*/
FL_EXPORT void fl_rtl_draw(const char*, int n, int x, int y);
diff --git a/TODO.utf8 b/TODO.utf8
index db61f016b..776da0d6b 100644
--- a/TODO.utf8
+++ b/TODO.utf8
@@ -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)
diff --git a/src/Fl_Font.H b/src/Fl_Font.H
index d609f79f0..6bb2e724e 100644
--- a/src/Fl_Font.H
+++ b/src/Fl_Font.H
@@ -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:
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
diff --git a/src/fl_font.cxx b/src/fl_font.cxx
index 41094a5c1..f9d6b9f7f 100644
--- a/src/fl_font.cxx
+++ b/src/fl_font.cxx
@@ -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 {
diff --git a/src/fl_font_mac.cxx b/src/fl_font_mac.cxx
index a7b10f463..3e9db0763 100644
--- a/src/fl_font_mac.cxx
+++ b/src/fl_font_mac.cxx
@@ -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);
diff --git a/src/fl_font_win32.cxx b/src/fl_font_win32.cxx
index 430536e5a..92279ffcb 100644
--- a/src/fl_font_win32.cxx
+++ b/src/fl_font_win32.cxx
@@ -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) {
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) {
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[] = {
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;
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) {
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;
diff --git a/src/fl_font_x.cxx b/src/fl_font_x.cxx
index a5248163a..a9b945b96 100644
--- a/src/fl_font_x.cxx
+++ b/src/fl_font_x.cxx
@@ -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);
//}
diff --git a/src/fl_font_xft.cxx b/src/fl_font_xft.cxx
index 027e1b3b2..f02d65af7 100644
--- a/src/fl_font_xft.cxx
+++ b/src/fl_font_xft.cxx
@@ -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;
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;
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) {
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) {
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);
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) {
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);
}
diff --git a/test/Makefile b/test/Makefile
index 79f731f93..eb249b433 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -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 = \
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)
resizebox$(EXEEXT): resizebox.o
+rotated_text$(EXEEXT): rotated_text.o
+
scroll$(EXEEXT): scroll.o
subwindow$(EXEEXT): subwindow.o