mirror of
https://git.code.sf.net/p/flwm/flwm
synced 2025-12-11 23:06:56 -05:00
Use fltk 1.3's ability to draw rotated text
This removes a huge and quite obsolete kludge that worked with X bitmap fonts only. Looks a lot nicer.
This commit is contained in:
14
Frame.C
14
Frame.C
@ -7,8 +7,6 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <FL/fl_draw.H>
|
||||
#include "Rotated.H"
|
||||
|
||||
|
||||
static Atom wm_state = 0;
|
||||
static Atom wm_change_state;
|
||||
@ -1257,6 +1255,7 @@ void Frame::draw() {
|
||||
fl_frame("AAAAWWJJTTNN",0,0,w(),h());
|
||||
#endif
|
||||
if (!flag(THIN_BORDER) && label_h > 3) {
|
||||
fl_push_clip(1, label_y, left, label_h);
|
||||
#ifdef SHOW_CLOCK
|
||||
if (active()) {
|
||||
int clkw = int(fl_width(clock_buf));
|
||||
@ -1275,8 +1274,9 @@ void Frame::draw() {
|
||||
// and the window height is short enough. For now, we'll
|
||||
// assume this is not enough of a problem to be concerned
|
||||
// about.
|
||||
draw_rotated90(clock_buf, 1, label_y+3, left-1, label_h-6,
|
||||
Fl_Align(FL_ALIGN_BOTTOM|FL_ALIGN_CLIP));
|
||||
fl_draw(90, clock_buf,
|
||||
(left + fl_height() + 1)/2 - fl_descent(),
|
||||
label_y+label_h-3);
|
||||
} else
|
||||
// Only show the clock on the active frame.
|
||||
XClearArea(fl_display, fl_xid(this), 1, label_y+3,
|
||||
@ -1284,8 +1284,10 @@ void Frame::draw() {
|
||||
#endif
|
||||
fl_color(labelcolor());
|
||||
fl_font(TITLE_FONT_SLOT, TITLE_FONT_SIZE);
|
||||
draw_rotated90(label(), 1, label_y+3, left-1, label_h-3,
|
||||
Fl_Align(FL_ALIGN_TOP|FL_ALIGN_CLIP));
|
||||
fl_draw(90, label(),
|
||||
(left + fl_height() + 1)/2 - fl_descent(),
|
||||
label_y+3+fl_width(label()));
|
||||
fl_pop_clip();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
5
Makefile
5
Makefile
@ -3,7 +3,7 @@ SHELL=/bin/sh
|
||||
PROGRAM = flwm
|
||||
VERSION = 1.02
|
||||
|
||||
CXXFILES = main.C Frame.C Rotated.C Menu.C FrameWindow.C Desktop.C Hotkeys.C
|
||||
CXXFILES = main.C Frame.C Menu.C FrameWindow.C Desktop.C Hotkeys.C
|
||||
|
||||
MANPAGE = 1
|
||||
|
||||
@ -80,6 +80,3 @@ OBJECTS_D = $(CXXFILES:.C=.do) $(CFILES:.c=.do)
|
||||
|
||||
$(PROGRAM_D) : $(OBJECTS_D)
|
||||
$(CXX) $(LDFLAGS) -o $(PROGRAM_D) $(OBJECTS_D) $(LIBS)
|
||||
|
||||
rotated_test: Rotated.o rotated_test.C
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o rotated_test rotated_test.C Rotated.o $(LIBS) $(LIBS)
|
||||
|
||||
442
Rotated.C
442
Rotated.C
@ -1,442 +0,0 @@
|
||||
// Rotated text drawing with X.
|
||||
|
||||
// Original code:
|
||||
// Copyright (c) 1992 Alan Richardson (mppa3@uk.ac.sussex.syma) */
|
||||
//
|
||||
// Modifications for fltk:
|
||||
// Copyright (c) 1997 Bill Spitzak (spitzak@d2.com)
|
||||
// Modifications are to draw using the current fl_font. All fonts
|
||||
// used are cached in local structures. This can get real expensive,
|
||||
// use "
|
||||
|
||||
/* xvertext, Copyright (c) 1992 Alan Richardson (mppa3@uk.ac.sussex.syma)
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted, provided
|
||||
* that the above copyright notice appear in all copies and that both the
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation. All work developed as a consequence of the use of
|
||||
* this program should duly acknowledge such use. No representations are
|
||||
* made about the suitability of this software for any purpose. It is
|
||||
* provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
// if not defined then portions not used by flwm are included:
|
||||
#define FLWM 1
|
||||
|
||||
/* ********************************************************************** */
|
||||
|
||||
#define FL_INTERNALS 1
|
||||
#include <FL/x.H>
|
||||
#if FL_MAJOR_VERSION < 2
|
||||
# define XWindow Window
|
||||
#endif
|
||||
#include <FL/fl_draw.H>
|
||||
#include "Rotated.H"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct BitmapStruct {
|
||||
int bit_w;
|
||||
int bit_h;
|
||||
Pixmap bm;
|
||||
};
|
||||
|
||||
struct XRotCharStruct {
|
||||
int ascent;
|
||||
int descent;
|
||||
int lbearing;
|
||||
int rbearing;
|
||||
int width;
|
||||
BitmapStruct glyph;
|
||||
};
|
||||
|
||||
struct XRotFontStruct {
|
||||
int dir;
|
||||
int height;
|
||||
int max_ascent;
|
||||
int max_descent;
|
||||
int max_char;
|
||||
int min_char;
|
||||
XFontStruct* xfontstruct;
|
||||
XRotCharStruct per_char[256];
|
||||
};
|
||||
|
||||
/* *** Load the rotated version of a given font *** */
|
||||
|
||||
static XRotFontStruct*
|
||||
XRotLoadFont(Display *dpy, XFontStruct* fontstruct, int dir)
|
||||
{
|
||||
char val;
|
||||
XImage *I1, *I2;
|
||||
Pixmap canvas;
|
||||
XWindow root;
|
||||
int screen;
|
||||
GC font_gc;
|
||||
char text[3];/*, errstr[300];*/
|
||||
|
||||
XRotFontStruct *rotfont;
|
||||
int ichar, i, j, index, boxlen = 60;
|
||||
int vert_w, vert_h, vert_len, bit_w, bit_h, bit_len;
|
||||
int min_char, max_char;
|
||||
unsigned char *vertdata, *bitdata;
|
||||
int ascent, descent, lbearing, rbearing;
|
||||
int on = 1, off = 0;
|
||||
|
||||
/* useful macros ... */
|
||||
screen = DefaultScreen(dpy);
|
||||
root = DefaultRootWindow(dpy);
|
||||
|
||||
/* create the depth 1 canvas bitmap ... */
|
||||
canvas = XCreatePixmap(dpy, root, boxlen, boxlen, 1);
|
||||
|
||||
/* create a GC ... */
|
||||
font_gc = XCreateGC(dpy, canvas, 0, 0);
|
||||
XSetBackground(dpy, font_gc, off);
|
||||
|
||||
XSetFont(dpy, font_gc, fontstruct->fid);
|
||||
|
||||
/* allocate space for rotated font ... */
|
||||
rotfont = (XRotFontStruct *)malloc((unsigned)sizeof(XRotFontStruct));
|
||||
|
||||
/* determine which characters are defined in font ... */
|
||||
min_char = fontstruct->min_char_or_byte2;
|
||||
if (min_char<0) min_char = 0;
|
||||
rotfont->min_char = min_char;
|
||||
max_char = fontstruct->max_char_or_byte2;
|
||||
if (max_char>255) max_char = 255;
|
||||
rotfont->max_char = max_char;
|
||||
|
||||
/* some overall font data ... */
|
||||
rotfont->dir = dir;
|
||||
rotfont->max_ascent = fontstruct->max_bounds.ascent;
|
||||
rotfont->max_descent = fontstruct->max_bounds.descent;
|
||||
rotfont->height = rotfont->max_ascent+rotfont->max_descent;
|
||||
|
||||
rotfont->xfontstruct = fontstruct;
|
||||
/* remember xfontstruct for `normal' text ... */
|
||||
if (dir != 0) {
|
||||
/* font needs rotation ... */
|
||||
/* loop through each character ... */
|
||||
for (ichar = min_char; ichar <= max_char; ichar++) {
|
||||
|
||||
index = ichar-fontstruct->min_char_or_byte2;
|
||||
|
||||
XCharStruct* charstruct;
|
||||
if (fontstruct->per_char)
|
||||
charstruct = fontstruct->per_char+index;
|
||||
else
|
||||
charstruct = &fontstruct->min_bounds;
|
||||
|
||||
/* per char dimensions ... */
|
||||
ascent = rotfont->per_char[ichar].ascent = charstruct->ascent;
|
||||
descent = rotfont->per_char[ichar].descent = charstruct->descent;
|
||||
lbearing = rotfont->per_char[ichar].lbearing = charstruct->lbearing;
|
||||
rbearing = rotfont->per_char[ichar].rbearing = charstruct->rbearing;
|
||||
rotfont->per_char[ichar].width = charstruct->width;
|
||||
|
||||
/* some space chars have zero body, but a bitmap can't have ... */
|
||||
if (!ascent && !descent)
|
||||
ascent = rotfont->per_char[ichar].ascent = 1;
|
||||
if (!lbearing && !rbearing)
|
||||
rbearing = rotfont->per_char[ichar].rbearing = 1;
|
||||
|
||||
/* glyph width and height when vertical ... */
|
||||
vert_w = rbearing-lbearing;
|
||||
vert_h = ascent+descent;
|
||||
|
||||
/* width in bytes ... */
|
||||
vert_len = (vert_w-1)/8+1;
|
||||
|
||||
XSetForeground(dpy, font_gc, off);
|
||||
XFillRectangle(dpy, canvas, font_gc, 0, 0, boxlen, boxlen);
|
||||
|
||||
/* draw the character centre top right on canvas ... */
|
||||
sprintf(text, "%c", ichar);
|
||||
XSetForeground(dpy, font_gc, on);
|
||||
XDrawImageString(dpy, canvas, font_gc, boxlen/2 - lbearing,
|
||||
boxlen/2 - descent, text, 1);
|
||||
|
||||
/* reserve memory for first XImage ... */
|
||||
vertdata = (unsigned char *) malloc((unsigned)(vert_len*vert_h));
|
||||
|
||||
/* create the XImage ... */
|
||||
I1 = XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap,
|
||||
0, (char *)vertdata, vert_w, vert_h, 8, 0);
|
||||
|
||||
// if (I1 == NULL) ... do something here
|
||||
|
||||
I1->byte_order = I1->bitmap_bit_order = MSBFirst;
|
||||
|
||||
/* extract character from canvas ... */
|
||||
XGetSubImage(dpy, canvas, boxlen/2, boxlen/2-vert_h,
|
||||
vert_w, vert_h, 1, XYPixmap, I1, 0, 0);
|
||||
I1->format = XYBitmap;
|
||||
|
||||
/* width, height of rotated character ... */
|
||||
if (dir == 2) {
|
||||
bit_w = vert_w;
|
||||
bit_h = vert_h;
|
||||
} else {
|
||||
bit_w = vert_h;
|
||||
bit_h = vert_w;
|
||||
}
|
||||
|
||||
/* width in bytes ... */
|
||||
bit_len = (bit_w-1)/8 + 1;
|
||||
|
||||
rotfont->per_char[ichar].glyph.bit_w = bit_w;
|
||||
rotfont->per_char[ichar].glyph.bit_h = bit_h;
|
||||
|
||||
/* reserve memory for the rotated image ... */
|
||||
bitdata = (unsigned char *)calloc((unsigned)(bit_h*bit_len), 1);
|
||||
|
||||
/* create the image ... */
|
||||
I2 = XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap, 0,
|
||||
(char *)bitdata, bit_w, bit_h, 8, 0);
|
||||
|
||||
// if (I2 == NULL) ... error
|
||||
|
||||
I2->byte_order = I2->bitmap_bit_order = MSBFirst;
|
||||
|
||||
/* map vertical data to rotated character ... */
|
||||
for (j = 0; j < bit_h; j++) {
|
||||
for (i = 0; i < bit_w; i++) {
|
||||
/* map bits ... */
|
||||
if (dir == 1)
|
||||
val = vertdata[i*vert_len + (vert_w-j-1)/8] &
|
||||
(128>>((vert_w-j-1)%8));
|
||||
|
||||
else if (dir == 2)
|
||||
val = vertdata[(vert_h-j-1)*vert_len + (vert_w-i-1)/8] &
|
||||
(128>>((vert_w-i-1)%8));
|
||||
|
||||
else
|
||||
val = vertdata[(vert_h-i-1)*vert_len + j/8] &
|
||||
(128>>(j%8));
|
||||
|
||||
if (val)
|
||||
bitdata[j*bit_len + i/8] = bitdata[j*bit_len + i/8] |
|
||||
(128>>(i%8));
|
||||
}
|
||||
}
|
||||
|
||||
/* create this character's bitmap ... */
|
||||
rotfont->per_char[ichar].glyph.bm =
|
||||
XCreatePixmap(dpy, root, bit_w, bit_h, 1);
|
||||
|
||||
/* put the image into the bitmap ... */
|
||||
XPutImage(dpy, rotfont->per_char[ichar].glyph.bm,
|
||||
font_gc, I2, 0, 0, 0, 0, bit_w, bit_h);
|
||||
|
||||
/* free the image and data ... */
|
||||
XDestroyImage(I1);
|
||||
XDestroyImage(I2);
|
||||
/* free((char *)bitdata); -- XDestroyImage does this
|
||||
free((char *)vertdata);*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (ichar = 0; ichar < min_char; ichar++)
|
||||
rotfont->per_char[ichar] = rotfont->per_char[int('?')];
|
||||
for (ichar = max_char+1; ichar < 256; ichar++)
|
||||
rotfont->per_char[ichar] = rotfont->per_char[int('?')];
|
||||
|
||||
/* free pixmap and GC ... */
|
||||
XFreePixmap(dpy, canvas);
|
||||
XFreeGC(dpy, font_gc);
|
||||
|
||||
return rotfont;
|
||||
}
|
||||
|
||||
/* *** Free the resources associated with a rotated font *** */
|
||||
|
||||
static void XRotUnloadFont(Display *dpy, XRotFontStruct *rotfont)
|
||||
{
|
||||
int ichar;
|
||||
|
||||
if (rotfont->dir != 0) {
|
||||
/* loop through each character, freeing its pixmap ... */
|
||||
for (ichar = rotfont->min_char; ichar <= rotfont->max_char; ichar++)
|
||||
XFreePixmap(dpy, rotfont->per_char[ichar].glyph.bm);
|
||||
}
|
||||
/* rotfont should never be referenced again ... */
|
||||
free((char *)rotfont);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* *** A front end to XRotPaintString : mimics XDrawString *** */
|
||||
|
||||
static void
|
||||
XRotDrawString(Display *dpy, XRotFontStruct *rotfont, Drawable drawable,
|
||||
GC gc, int x, int y, const char *str, int len)
|
||||
{
|
||||
int i, xp, yp, dir, ichar;
|
||||
|
||||
if (str == NULL || len<1) return;
|
||||
|
||||
dir = rotfont->dir;
|
||||
|
||||
/* a horizontal string is easy ... */
|
||||
if (dir == 0) {
|
||||
XSetFont(dpy, gc, rotfont->xfontstruct->fid);
|
||||
XDrawString(dpy, drawable, gc, x, y, str, len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* vertical or upside down ... */
|
||||
|
||||
XSetFillStyle(dpy, gc, FillStippled);
|
||||
|
||||
/* loop through each character in string ... */
|
||||
for (i = 0; i<len; i++) {
|
||||
ichar = ((unsigned char*)str)[i];
|
||||
|
||||
/* suitable offset ... */
|
||||
if (dir == 1) {
|
||||
xp = x-rotfont->per_char[ichar].ascent;
|
||||
yp = y-rotfont->per_char[ichar].rbearing;
|
||||
}
|
||||
else if (dir == 2) {
|
||||
xp = x-rotfont->per_char[ichar].rbearing;
|
||||
yp = y-rotfont->per_char[ichar].descent+1;
|
||||
}
|
||||
else {
|
||||
xp = x-rotfont->per_char[ichar].descent+1;
|
||||
yp = y+rotfont->per_char[ichar].lbearing;
|
||||
}
|
||||
|
||||
/* draw the glyph ... */
|
||||
XSetStipple(dpy, gc, rotfont->per_char[ichar].glyph.bm);
|
||||
|
||||
XSetTSOrigin(dpy, gc, xp, yp);
|
||||
|
||||
XFillRectangle(dpy, drawable, gc, xp, yp,
|
||||
rotfont->per_char[ichar].glyph.bit_w,
|
||||
rotfont->per_char[ichar].glyph.bit_h);
|
||||
|
||||
/* advance position ... */
|
||||
if (dir == 1)
|
||||
y -= rotfont->per_char[ichar].width;
|
||||
else if (dir == 2)
|
||||
x -= rotfont->per_char[ichar].width;
|
||||
else
|
||||
y += rotfont->per_char[ichar].width;
|
||||
}
|
||||
XSetFillStyle(dpy, gc, FillSolid);
|
||||
}
|
||||
|
||||
#ifndef FLWM
|
||||
/* *** Return the width of a string *** */
|
||||
|
||||
static int XRotTextWidth(XRotFontStruct *rotfont, const char *str, int len)
|
||||
{
|
||||
int i, width = 0, ichar;
|
||||
|
||||
if (str == NULL) return 0;
|
||||
|
||||
if (rotfont->dir == 0)
|
||||
width = XTextWidth(rotfont->xfontstruct, str, strlen(str));
|
||||
|
||||
else
|
||||
for (i = 0; i<len; i++) {
|
||||
width += rotfont->per_char[((unsigned char*)str)[i]].width;
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
// the public functions use the fltk global variables for font & gc:
|
||||
|
||||
static XRotFontStruct* font;
|
||||
|
||||
static void setrotfont(int angle) {
|
||||
/* make angle positive ... */
|
||||
if (angle < 0) do angle += 360; while (angle < 0);
|
||||
/* get nearest vertical or horizontal direction ... */
|
||||
int dir = ((angle+45)/90)%4;
|
||||
if (font) {
|
||||
if (font->xfontstruct == fl_xfont && font->dir == dir) return;
|
||||
XRotUnloadFont(fl_display, font);
|
||||
}
|
||||
font = XRotLoadFont(fl_display, fl_xfont, dir);
|
||||
}
|
||||
|
||||
void draw_rotated(const char* text, int n, int x, int y, int angle) {
|
||||
if (!text || !*text) return;
|
||||
setrotfont(angle);
|
||||
XRotDrawString(fl_display, font, fl_window, fl_gc, x, y, text, n);
|
||||
}
|
||||
|
||||
#if !defined(FLWM) || FL_MAJOR_VERSION>=2
|
||||
void draw_rotated(const char* text, int x, int y, int angle) {
|
||||
if (!text || !*text) return;
|
||||
draw_rotated(text, strlen(text), x, y, angle);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void draw_rot90(const char* str, int n, int x, int y) {
|
||||
draw_rotated(str, n, y, -x, 90);
|
||||
}
|
||||
void draw_rotated90(
|
||||
const char* str, // the (multi-line) string
|
||||
int x, int y, int w, int h, // bounding box
|
||||
Fl_Align align) {
|
||||
if (!str || !*str) return;
|
||||
if (w && h && !fl_not_clipped(x, y, w, h)) return;
|
||||
if (align & FL_ALIGN_CLIP) fl_clip(x, y, w, h);
|
||||
#if FL_MAJOR_VERSION>1
|
||||
setrotfont(90);
|
||||
int a = font->xfontstruct->ascent;
|
||||
int d = font->xfontstruct->descent;
|
||||
XRotDrawString(fl_display, font, fl_window, fl_gc,
|
||||
x+(w+a-d+1)/2, y+h, str, strlen(str));
|
||||
#else
|
||||
int a1 = align&(-16);
|
||||
if (align & FL_ALIGN_LEFT) a1 |= FL_ALIGN_TOP;
|
||||
if (align & FL_ALIGN_RIGHT) a1 |= FL_ALIGN_BOTTOM;
|
||||
if (align & FL_ALIGN_TOP) a1 |= FL_ALIGN_RIGHT;
|
||||
if (align & FL_ALIGN_BOTTOM) a1 |= FL_ALIGN_LEFT;
|
||||
fl_draw(str, -(y+h), x, h, w, (Fl_Align)a1, draw_rot90);
|
||||
#endif
|
||||
if (align & FL_ALIGN_CLIP) fl_pop_clip();
|
||||
}
|
||||
|
||||
#ifndef FLWM
|
||||
static void draw_rot180(const char* str, int n, int x, int y) {
|
||||
draw_rotated(str, n, -x, -y, 180);
|
||||
}
|
||||
void draw_rotated180(
|
||||
const char* str, // the (multi-line) string
|
||||
int x, int y, int w, int h, // bounding box
|
||||
Fl_Align align) {
|
||||
int a1 = align&(-16);
|
||||
if (align & FL_ALIGN_LEFT) a1 |= FL_ALIGN_RIGHT;
|
||||
if (align & FL_ALIGN_RIGHT) a1 |= FL_ALIGN_LEFT;
|
||||
if (align & FL_ALIGN_TOP) a1 |= FL_ALIGN_BOTTOM;
|
||||
if (align & FL_ALIGN_BOTTOM) a1 |= FL_ALIGN_TOP;
|
||||
fl_draw(str, -(x+w), -(y+h), w, h, (Fl_Align)a1, draw_rot180);
|
||||
}
|
||||
|
||||
static void draw_rot270(const char* str, int n, int x, int y) {
|
||||
draw_rotated(str, n, -y, x, 270);
|
||||
}
|
||||
void draw_rotated270(
|
||||
const char* str, // the (multi-line) string
|
||||
int x, int y, int w, int h, // bounding box
|
||||
Fl_Align align) {
|
||||
int a1 = align&(-16);
|
||||
if (align & FL_ALIGN_LEFT) a1 |= FL_ALIGN_BOTTOM;
|
||||
if (align & FL_ALIGN_RIGHT) a1 |= FL_ALIGN_TOP;
|
||||
if (align & FL_ALIGN_TOP) a1 |= FL_ALIGN_LEFT;
|
||||
if (align & FL_ALIGN_BOTTOM) a1 |= FL_ALIGN_RIGHT;
|
||||
fl_draw(str, y, -(x+w), h, w, (Fl_Align)a1, draw_rot270);
|
||||
}
|
||||
#endif
|
||||
|
||||
18
Rotated.H
18
Rotated.H
@ -1,18 +0,0 @@
|
||||
// Rotated text drawing with X.
|
||||
|
||||
// Original code:
|
||||
// Copyright (c) 1992 Alan Richardson (mppa3@uk.ac.sussex.syma) */
|
||||
//
|
||||
// Modifications for fltk:
|
||||
// Copyright (c) 1997 Bill Spitzak (spitzak@d2.com)
|
||||
|
||||
#ifndef Rotated_H
|
||||
#define Rotated_H
|
||||
|
||||
void draw_rotated(const char* text, int n, int x, int y, int angle);
|
||||
void draw_rotated(const char* text, int x, int y, int angle);
|
||||
void draw_rotated90(const char*, int x, int y, int w, int h, Fl_Align);
|
||||
void draw_rotated270(const char*, int x, int y, int w, int h, Fl_Align);
|
||||
void draw_rotated180(const char*, int x, int y, int w, int h, Fl_Align);
|
||||
|
||||
#endif
|
||||
117
rotated_test.C
117
rotated_test.C
@ -1,117 +0,0 @@
|
||||
// Test the xvertext routines for rotated text
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Double_Window.H>
|
||||
#include <FL/Fl_Box.H>
|
||||
#include <FL/Fl_Hor_Value_Slider.H>
|
||||
#include <FL/Fl_Toggle_Button.H>
|
||||
#include <FL/Fl_Input.H>
|
||||
#include <FL/Fl_Choice.H>
|
||||
#include <FL/fl_draw.H>
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Rotated.H"
|
||||
|
||||
class RotText : public Fl_Box {
|
||||
void draw();
|
||||
public:
|
||||
RotText(int X, int Y, int W, int H, const char* L = 0) :
|
||||
Fl_Box(X,Y,W,H,L) {}
|
||||
};
|
||||
|
||||
void RotText::draw() {
|
||||
draw_box();
|
||||
fl_color(FL_BLACK);
|
||||
fl_font(labelfont(), labelsize());
|
||||
draw_rotated90(label(), x(), y(), w(), h(), align());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
Fl_Toggle_Button *leftb,*rightb,*topb,*bottomb,*insideb,*clipb,*wrapb;
|
||||
RotText *text;
|
||||
Fl_Input *input;
|
||||
Fl_Hor_Value_Slider *fonts;
|
||||
Fl_Hor_Value_Slider *sizes;
|
||||
Fl_Double_Window *window;
|
||||
|
||||
void button_cb(Fl_Widget *,void *) {
|
||||
int i = 0;
|
||||
if (leftb->value()) i |= FL_ALIGN_LEFT;
|
||||
if (rightb->value()) i |= FL_ALIGN_RIGHT;
|
||||
if (topb->value()) i |= FL_ALIGN_TOP;
|
||||
if (bottomb->value()) i |= FL_ALIGN_BOTTOM;
|
||||
if (insideb->value()) i |= FL_ALIGN_INSIDE;
|
||||
if (clipb->value()) i |= FL_ALIGN_CLIP;
|
||||
if (wrapb->value()) i |= FL_ALIGN_WRAP;
|
||||
text->align(i);
|
||||
window->redraw();
|
||||
}
|
||||
|
||||
void font_cb(Fl_Widget *,void *) {
|
||||
text->labelfont(int(fonts->value()));
|
||||
window->redraw();
|
||||
}
|
||||
|
||||
void size_cb(Fl_Widget *,void *) {
|
||||
text->labelsize(int(sizes->value()));
|
||||
window->redraw();
|
||||
}
|
||||
|
||||
void input_cb(Fl_Widget *,void *) {
|
||||
text->label(input->value());
|
||||
window->redraw();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
window = new Fl_Double_Window(400,400);
|
||||
|
||||
input = new Fl_Input(50,0,350,25);
|
||||
input->static_value("The quick brown fox jumped over the lazy dog.");
|
||||
input->when(FL_WHEN_CHANGED);
|
||||
input->callback(input_cb);
|
||||
|
||||
sizes= new Fl_Hor_Value_Slider(50,25,350,25,"Size:");
|
||||
sizes->align(FL_ALIGN_LEFT);
|
||||
sizes->bounds(1,64);
|
||||
sizes->step(1);
|
||||
sizes->value(14);
|
||||
sizes->callback(size_cb);
|
||||
|
||||
fonts=new Fl_Hor_Value_Slider(50,50,350,25,"Font:");
|
||||
fonts->align(FL_ALIGN_LEFT);
|
||||
fonts->bounds(0,15);
|
||||
fonts->step(1);
|
||||
fonts->value(0);
|
||||
fonts->callback(font_cb);
|
||||
|
||||
Fl_Group *g = new Fl_Group(50,75,400,25);
|
||||
leftb = new Fl_Toggle_Button(50,75,50,25,"left");
|
||||
leftb->callback(button_cb);
|
||||
rightb = new Fl_Toggle_Button(100,75,50,25,"right");
|
||||
rightb->callback(button_cb);
|
||||
topb = new Fl_Toggle_Button(150,75,50,25,"top");
|
||||
topb->callback(button_cb);
|
||||
bottomb = new Fl_Toggle_Button(200,75,50,25,"bottom");
|
||||
bottomb->callback(button_cb);
|
||||
insideb = new Fl_Toggle_Button(250,75,50,25,"inside");
|
||||
insideb->callback(button_cb);
|
||||
wrapb = new Fl_Toggle_Button(300,75,50,25,"wrap");
|
||||
wrapb->callback(button_cb);
|
||||
clipb = new Fl_Toggle_Button(350,75,50,25,"clip");
|
||||
clipb->callback(button_cb);
|
||||
g->resizable(insideb);
|
||||
g->end();
|
||||
|
||||
text= new RotText(100,225,200,100,input->value());
|
||||
text->box(FL_FRAME_BOX);
|
||||
text->align(FL_ALIGN_CENTER);
|
||||
window->resizable(text);
|
||||
window->show(argc,argv);
|
||||
return Fl::run();
|
||||
}
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
||||
Reference in New Issue
Block a user