summaryrefslogtreecommitdiffstats
path: root/tdegtk/tqtcairopainter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdegtk/tqtcairopainter.cpp')
-rw-r--r--tdegtk/tqtcairopainter.cpp320
1 files changed, 286 insertions, 34 deletions
diff --git a/tdegtk/tqtcairopainter.cpp b/tdegtk/tqtcairopainter.cpp
index 8f917e1..05e9a0a 100644
--- a/tdegtk/tqtcairopainter.cpp
+++ b/tdegtk/tqtcairopainter.cpp
@@ -27,9 +27,11 @@
#include "tqimage.h"
#include "tqfile.h"
#include "tqpaintdevicemetrics.h"
+
#undef Qt
#define CAIRO_PIXEL_OFFSET (0.5)
+#define CAIRO_FONT_SIZE_FUDGE_FACTOR (1.4)
#define SET_BIT(x, y) (x |= 1 << y)
#define TEST_BIT(x, y) ((x & (1 << y)) >> y)
@@ -219,7 +221,7 @@ void TQt3CairoPaintDevice::updatePen(bool backgroundStroke) {
cairo_set_line_width(m_painter, ((!allow_zero_lw) && (m_pen.width() == 0)) ? 1 : m_pen.width());
TQRgb color = (backgroundStroke)?m_bgColor.rgb():m_pen.color().rgb();
- cairo_set_source_rgba(m_painter, tqRed(color), tqGreen(color), tqBlue(color), tqAlpha(color));
+ cairo_set_source_rgba(m_painter, tqRed(color)/255.0, tqGreen(color)/255.0, tqBlue(color)/255.0, tqAlpha(color)/255.0);
}
void TQt3CairoPaintDevice::updateBrush(bool backgroundStroke, cairo_fill_rule_t fillMethod) {
@@ -229,7 +231,7 @@ void TQt3CairoPaintDevice::updateBrush(bool backgroundStroke, cairo_fill_rule_t
if (backgroundStroke) {
TQRgb color = m_bgColor.rgb();
- cairo_pattern_t* pattern = cairo_pattern_create_rgba(tqRed(color), tqGreen(color), tqBlue(color), tqAlpha(color));
+ cairo_pattern_t* pattern = cairo_pattern_create_rgba(tqRed(color)/255.0, tqGreen(color)/255.0, tqBlue(color)/255.0, tqAlpha(color)/255.0);
cairo_set_source(m_painter, pattern);
cairo_pattern_set_extend(cairo_get_source(m_painter), CAIRO_EXTEND_REPEAT);
cairo_pattern_destroy(pattern);
@@ -308,7 +310,7 @@ void TQt3CairoPaintDevice::updateBrush(bool backgroundStroke, cairo_fill_rule_t
int bit = 7;
for (x=0; x<d; x++) {
for (y=0; y<d; y++) {
- brushImage.setPixel(x, y, (TEST_BIT(pat[byte], bit))?color:0x00000000);
+ brushImage.setPixel(y, x, (TEST_BIT(pat[byte], bit))?color:0x00000000);
bit--;
if (bit < 0) {
bit = 7;
@@ -325,6 +327,9 @@ void TQt3CairoPaintDevice::updateBrush(bool backgroundStroke, cairo_fill_rule_t
cairo_surface_t* brushSurface = TQImageToCairoSurface(brushImage);
cairo_pattern_t* pattern = cairo_pattern_create_for_surface(brushSurface);
+ cairo_matrix_t brush_translation_matrix;
+ cairo_matrix_init_translate(&brush_translation_matrix, m_brushOrigin.x(), m_brushOrigin.y());
+ cairo_pattern_set_matrix(pattern, &brush_translation_matrix);
cairo_set_source(m_painter, pattern);
cairo_pattern_set_extend(cairo_get_source(m_painter), CAIRO_EXTEND_REPEAT);
cairo_pattern_destroy(pattern);
@@ -332,7 +337,7 @@ void TQt3CairoPaintDevice::updateBrush(bool backgroundStroke, cairo_fill_rule_t
}
else {
TQRgb color = m_brush.color().rgb();
- cairo_pattern_t* pattern = cairo_pattern_create_rgba(tqRed(color), tqGreen(color), tqBlue(color), tqAlpha(color));
+ cairo_pattern_t* pattern = cairo_pattern_create_rgba(tqRed(color)/255.0, tqGreen(color)/255.0, tqBlue(color)/255.0, tqAlpha(color)/255.0);
cairo_set_source(m_painter, pattern);
cairo_pattern_set_extend(cairo_get_source(m_painter), CAIRO_EXTEND_REPEAT);
cairo_pattern_destroy(pattern);
@@ -364,7 +369,7 @@ void TQt3CairoPaintDevice::drawPolygon(const TQPointArray* pointarray, bool wind
if ((m_brush.style() != TQBrush::NoBrush) && fill) {
first = true;
for (i=0;i<pointarray->count();i++) {
- pointarray->point(i, &x, &y );
+ pointarray->point(i, &x, &y);
if (first) {
cairo_move_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
first = false;
@@ -381,7 +386,7 @@ void TQt3CairoPaintDevice::drawPolygon(const TQPointArray* pointarray, bool wind
if (m_pen.style() != TQPen::NoPen) {
first = true;
for (i=0;i<pointarray->count();i++) {
- pointarray->point(i, &x, &y );
+ pointarray->point(i, &x, &y);
if (first) {
cairo_move_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
first = false;
@@ -537,6 +542,144 @@ void TQt3CairoPaintDevice::drawChord(int x, int y, int w, int h, int a, int alen
return;
}
+void TQt3CairoPaintDevice::pangoSetupTextPath(PangoLayout *layout, const char* text) {
+ PangoFontDescription *desc;
+
+ pango_layout_set_text(layout, text, -1);
+
+ desc = pango_font_description_new();
+
+ // FIXME
+ // overline and a handful of other flags are not supported by Pango!
+ TQString family = m_font.family();
+// bool bold = m_font.bold();
+ bool italic = m_font.italic();
+ bool underline = m_font.underline();
+// bool overline = m_font.overline();
+ bool strikeout = m_font.strikeOut();
+// bool fixedPitch = m_font.fixedPitch();
+ int stretch = m_font.stretch();
+ int weight = m_font.weight();
+
+ int pixelSize = m_font.pixelSize();
+ bool usePixelSize = (pixelSize>=0);
+ float pointSizeFloat = m_font.pointSizeFloat();
+ bool usePointSize = (pointSizeFloat>=0);
+
+ TQFont::StyleStrategy qt3fontstrategy = m_font.styleStrategy();
+
+ PangoWeight pangoWeight;
+ switch (weight) {
+ case TQFont::Light:
+ pangoWeight = PANGO_WEIGHT_LIGHT;
+ break;
+ case TQFont::Normal:
+ pangoWeight = PANGO_WEIGHT_NORMAL;
+ break;
+ case TQFont::DemiBold:
+ pangoWeight = PANGO_WEIGHT_SEMIBOLD;
+ break;
+ case TQFont::Bold:
+ pangoWeight = PANGO_WEIGHT_BOLD;
+ break;
+ case TQFont::Black:
+ pangoWeight = PANGO_WEIGHT_HEAVY;
+ break;
+ }
+
+ PangoStretch pangoStretch;
+ switch (stretch) {
+ case TQFont::UltraCondensed:
+ pangoStretch = PANGO_STRETCH_ULTRA_CONDENSED;
+ break;
+ case TQFont::ExtraCondensed:
+ pangoStretch = PANGO_STRETCH_EXTRA_CONDENSED;
+ break;
+ case TQFont::Condensed:
+ pangoStretch = PANGO_STRETCH_CONDENSED;
+ break;
+ case TQFont::SemiCondensed:
+ pangoStretch = PANGO_STRETCH_SEMI_CONDENSED;
+ break;
+ case TQFont::Unstretched:
+ pangoStretch = PANGO_STRETCH_NORMAL;
+ break;
+ case TQFont::SemiExpanded:
+ pangoStretch = PANGO_STRETCH_SEMI_EXPANDED;
+ break;
+ case TQFont::Expanded:
+ pangoStretch = PANGO_STRETCH_EXPANDED;
+ break;
+ case TQFont::ExtraExpanded:
+ pangoStretch = PANGO_STRETCH_EXTRA_EXPANDED;
+ break;
+ case TQFont::UltraExpanded:
+ pangoStretch = PANGO_STRETCH_ULTRA_EXPANDED;
+ break;
+ }
+
+ pango_font_description_set_family(desc, family.ascii());
+ if (usePixelSize) {
+ pango_font_description_set_absolute_size(desc, pixelSize*PANGO_SCALE);
+ }
+ if (usePointSize) {
+ pango_font_description_set_absolute_size(desc, pointSizeFloat*PANGO_SCALE*CAIRO_FONT_SIZE_FUDGE_FACTOR);
+ }
+ pango_font_description_set_style(desc, (italic)?PANGO_STYLE_ITALIC:PANGO_STYLE_NORMAL);
+ pango_font_description_set_weight(desc, pangoWeight);
+ pango_font_description_set_stretch(desc, pangoStretch);
+
+#if 0
+ if (qt3fontstrategy & TQFont::PreferDefault) // FIXME Set Cairo/Pango to follow this hint
+ if (qt3fontstrategy & TQFont::PreferBitmap) // FIXME Set Cairo/Pango to follow this hint
+ if (qt3fontstrategy & TQFont::PreferDevice) // FIXME Set Cairo/Pango to follow this hint
+ if (qt3fontstrategy & TQFont::PreferMatch) // FIXME Set Cairo/Pango to follow this hint
+ if (qt3fontstrategy & TQFont::PreferQuality) // FIXME Set Cairo/Pango to follow this hint
+ if (qt3fontstrategy & TQFont::PreferAntialias) // FIXME Set Cairo/Pango to follow this hint
+ if (qt3fontstrategy & TQFont::NoAntialias) // FIXME Set Cairo/Pango to follow this hint
+ if (qt3fontstrategy & TQFont::OpenGLCompatible) // FIXME Set Cairo/Pango to follow this hint
+#endif
+
+ pango_layout_set_font_description(layout, desc);
+
+ PangoAttrList* attr_list = pango_attr_list_new();
+ pango_attr_list_insert(attr_list, pango_attr_underline_new((underline)?PANGO_UNDERLINE_SINGLE:PANGO_UNDERLINE_NONE));
+ pango_attr_list_insert(attr_list, pango_attr_strikethrough_new(strikeout));
+ pango_layout_set_attributes(layout, attr_list);
+ pango_attr_list_unref(attr_list);
+
+ pango_font_description_free(desc);
+}
+
+void TQt3CairoPaintDevice::drawText(TQPainter *p, int x, int y, const TQString &str, int pos, int len, TQPainter::TextDirection dir, bool baseline) {
+ if ((!m_painter) || (!p)) {
+ return;
+ }
+
+ PangoLayout *layout;
+ layout = pango_cairo_create_layout(m_painter);
+
+ TQFont::StyleStrategy qt3fontstrategy = m_font.styleStrategy();
+ pangoSetupTextPath(layout, str.utf8());
+
+ int baseline_y = pango_layout_get_baseline(layout)/PANGO_SCALE;
+ cairo_new_path(m_painter);
+ cairo_move_to(m_painter, x, (baseline)?y-baseline_y:y);
+ updatePen(FALSE);
+
+ pango_cairo_update_layout(m_painter, layout);
+ pango_cairo_layout_path(m_painter, layout);
+
+ if ((qt3fontstrategy & TQFont::PreferOutline) || (qt3fontstrategy & TQFont::ForceOutline)) {
+ cairo_stroke_preserve(m_painter);
+ }
+ else {
+ cairo_fill(m_painter);
+ }
+
+ g_object_unref(layout);
+}
+
/*!
\class TQt3CairoPaintDevice tdeqt4painter.h
\brief The TQt3CairoPaintDevice class is a paint device that translates
@@ -575,8 +718,6 @@ TQt3CairoPaintDevice::~TQt3CairoPaintDevice()
bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
{
- Q_UNUSED(pt);
-
unsigned int i;
double x;
@@ -602,14 +743,6 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
x2 = p[1].point->x();
y2 = p[1].point->y();
}
-// if ((c == PdcDrawPolyline) || (c == PdcDrawPolygon) || (c == PdcDrawLineSegments) || (c == PdcDrawCubicBezier)) {
-// TQPointArray qt3parray = *p[0].ptarr;
-// qt4polygon.resize(qt3parray.count());
-// for (i=0;i<qt3parray.count();i++) {
-// qt3parray.point(i, &x, &y );
-// qt4polygon.setPoint(i, x, y);
-// }
-// }
if ((c == PdcDrawRect) || (c == PdcDrawRoundRect) || (c == PdcDrawEllipse) || (c == PdcDrawArc) || (c == PdcDrawPie) || (c == PdcDrawChord)) {
x = p[0].rect->x();
y = p[0].rect->y();
@@ -681,7 +814,7 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
}
else {
#if defined(QT_CHECK_RANGE)
- tqWarning( "TQt3CairoPaintDevice::cmd: TQPainter::begin must be called before PdcDrawRect" );
+ tqWarning( "TQt3CairoPaintDevice::cmd: TQPainter::begin must be called before PdcDrawRect" );
#endif
}
break;
@@ -730,14 +863,30 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
cairo_restore(m_painter);
}
break;
-#if 0
case PdcDrawLineSegments:
- index = 0;
- count = -1;
- lineCount = (count == -1) ? (qt4polygon.size() - index) / 2 : count;
- m_qt4painter->drawLines(qt4polygon.constData() + index * 2, lineCount);
+ if (m_painter) {
+ cairo_save(m_painter);
+ if (p) {
+ int x;
+ int y;
+ int x2;
+ int y2;
+ const TQPointArray* pointarray = p[0].ptarr;
+ if (pointarray) {
+ if (m_pen.style() != TQPen::NoPen) {
+ for (i=0;i<pointarray->count();i=i+2) {
+ pointarray->point(i+0, &x, &y);
+ pointarray->point(i+1, &x2, &y2);
+ cairo_move_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
+ cairo_line_to(m_painter, x2+CAIRO_PIXEL_OFFSET, y2+CAIRO_PIXEL_OFFSET);
+ dualStrokePen();
+ }
+ }
+ }
+ }
+ cairo_restore(m_painter);
+ }
break;
-#endif
case PdcDrawPolyline:
if (p) {
drawPolygon(p[0].ptarr, false, false, true);
@@ -748,22 +897,56 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
drawPolygon(p[0].ptarr, p[1].ival, true, true);
}
break;
-#if 0
case PdcDrawCubicBezier:
- index = 0;
- path.moveTo(qt4polygon.at(index));
- path.cubicTo(qt4polygon.at(index+1), qt4polygon.at(index+2), qt4polygon.at(index+3));
- m_qt4painter->strokePath(path, m_qt4painter->pen());
+ if (m_painter) {
+ cairo_save(m_painter);
+ if (p) {
+ int x;
+ int y;
+ int x2;
+ int y2;
+ int x3;
+ int y3;
+ int x4;
+ int y4;
+ const TQPointArray* pointarray = p[0].ptarr;
+ if (pointarray) {
+ if (m_pen.style() != TQPen::NoPen) {
+ for (i=0;i<pointarray->count();i=i+4) {
+ pointarray->point(i+0, &x, &y);
+ pointarray->point(i+1, &x2, &y2);
+ pointarray->point(i+2, &x3, &y3);
+ pointarray->point(i+3, &x4, &y4);
+ cairo_move_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
+ cairo_curve_to(m_painter, x2+CAIRO_PIXEL_OFFSET, y2+CAIRO_PIXEL_OFFSET, x3+CAIRO_PIXEL_OFFSET, y3+CAIRO_PIXEL_OFFSET, x4+CAIRO_PIXEL_OFFSET, y4+CAIRO_PIXEL_OFFSET);
+ dualStrokePen();
+ }
+ }
+ }
+ }
+ cairo_restore(m_painter);
+ }
break;
+#if 0
case PdcDrawText:
+ // NOTE
+ // drawText baseline = FALSE for this!
m_qt4painter->drawText( qt4point1, qt4string );
break;
case PdcDrawTextFormatted:
m_qt4painter->drawText( qt4rect, qt4formattedtextflags, qt4string );
break;
+#endif
case PdcDrawText2:
- m_qt4painter->drawText( qt4point1, qt4string );
+ if (m_painter) {
+ cairo_save(m_painter);
+ if (p) {
+ TQString string = *p[1].str;
+ drawText(pt, p[0].rect->x()+CAIRO_PIXEL_OFFSET, p[0].rect->y()+CAIRO_PIXEL_OFFSET, string, 0, -1, TQPainter::Auto, TRUE);
+ }
+ }
break;
+#if 0
case PdcDrawText2Formatted:
m_qt4painter->drawText( qt4rect, qt4formattedtextflags, qt4string );
break;
@@ -791,6 +974,7 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
m_painter = cairo_create(m_surface);
m_pen = TQPen();
m_brush = TQBrush();
+ m_brushOrigin = TQPoint(0,0);
}
break;
case PdcEnd:
@@ -818,17 +1002,85 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
m_bgColorMode = (TQt::BGMode)p[0].ival;
}
break;
-#if 0
case PdcSetROP:
- m_qt4painter->setCompositionMode(qt4compositionmode);
+ if ((p) && (m_painter)) {
+ cairo_operator_t cairoCompositionMode = CAIRO_OPERATOR_OVER;
+ TQt::RasterOp rop = (TQt::RasterOp)p[0].ival;
+ switch (rop) {
+ case TQPainter::CopyROP:
+ cairoCompositionMode=CAIRO_OPERATOR_OVER;
+ break;
+ case TQPainter::OrROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ case TQPainter::XorROP:
+ // While this is not a 'real' XOR, if the source color is white (1.0) it should work well enough (i.e. reverse itself on a second application)...
+ cairoCompositionMode=CAIRO_OPERATOR_DIFFERENCE;
+ break;
+ case TQPainter::NotAndROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ case TQPainter::NotCopyROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ case TQPainter::NotOrROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ case TQPainter::NotXorROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ case TQPainter::AndROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ case TQPainter::NotROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ case TQPainter::ClearROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ case TQPainter::SetROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ case TQPainter::NopROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ case TQPainter::AndNotROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ case TQPainter::OrNotROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ case TQPainter::NandROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ case TQPainter::NorROP:
+ tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n\r", rop);
+ break;
+ default:
+ cairoCompositionMode=CAIRO_OPERATOR_OVER;
+#if defined(QT_CHECK_RANGE)
+ tqWarning( "TDEQt4PaintDevice::cmd: Unhandled raster operation %d", rop );
+#endif
+ }
+ cairo_set_operator(m_painter, cairoCompositionMode);
+ }
break;
case PdcSetBrushOrigin:
- m_qt4painter->setBrushOrigin( qt4point1 );
+ if (p) {
+ const TQPoint* point = p[0].point;
+ if (point) {
+ m_brushOrigin = *point;
+ }
+ }
break;
case PdcSetFont:
- m_qt4painter->setFont( qt4font );
+ if (p) {
+ const TQFont* font = p[0].font;
+ if (font) {
+ m_font = *font;
+ }
+ }
break;
-#endif
case PdcSetPen:
if (p) {
const TQPen* pen = p[0].pen;