diff --git a/tdegtk/tqtcairopainter.cpp b/tdegtk/tqtcairopainter.cpp index a552ee9..75d1b99 100644 --- a/tdegtk/tqtcairopainter.cpp +++ b/tdegtk/tqtcairopainter.cpp @@ -100,7 +100,7 @@ void TQt3CairoPaintDevice::resetIntermediateSurface() { void TQt3CairoPaintDevice::transferIntermediateSurface() { cairo_surface_flush(m_intermediateSurface); - if (m_clipRegion.isNull()) { + if (!m_clipRegionEnabled) { // Clipping disabled cairo_set_source_surface(m_devicePainter, m_intermediateSurface, 0, 0); cairo_set_operator(m_devicePainter, CAIRO_OPERATOR_SOURCE); @@ -686,7 +686,7 @@ void TQt3CairoPaintDevice::pangoSetupTextPath(PangoLayout *layout, const char* t 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) { +void TQt3CairoPaintDevice::drawText(TQPainter *p, int x, int y, const TQString &str) { if ((!m_painter) || (!p)) { return; } @@ -699,7 +699,7 @@ void TQt3CairoPaintDevice::drawText(TQPainter *p, int x, int y, const TQString & 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); + cairo_move_to(m_painter, x, y-baseline_y); updatePen(FALSE); pango_cairo_update_layout(m_painter, layout); @@ -717,6 +717,101 @@ void TQt3CairoPaintDevice::drawText(TQPainter *p, int x, int y, const TQString & transferIntermediateSurface(); } +void TQt3CairoPaintDevice::drawTextInRect(TQPainter *p, TQRect rect, int textFlags, const TQString &str) { + if ((!m_painter) || (!p)) { + return; + } + + PangoLayout *layout; + layout = pango_cairo_create_layout(m_painter); + + TQFont::StyleStrategy qt3fontstrategy = m_font.styleStrategy(); + pangoSetupTextPath(layout, str.utf8()); + + pango_layout_set_width(layout, rect.width()*PANGO_SCALE); + + int fudgedOffsetY = 0; + + // Layout flags + if (textFlags & TQt::SingleLine) { + // Pango special case to force rendering of only one line of text + pango_layout_set_height(layout, 0); + } + if (!(textFlags & TQt::DontClip)) { + cairo_rectangle(m_painter, rect.x()+CAIRO_PIXEL_OFFSET, rect.y()+CAIRO_PIXEL_OFFSET, rect.width(), rect.height()); + cairo_clip(m_painter); + } + if (textFlags & TQt::ExpandTabs) { + // FIXME + } + if (textFlags & TQt::ShowPrefix) { + // FIXME + } + if (textFlags & TQt::WordBreak) { + pango_layout_set_wrap(layout, PANGO_WRAP_WORD); + } + if (textFlags & TQt::BreakAnywhere) { + pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); + } + if (textFlags & TQt::NoAccel) { + // FIXME + } + + PangoRectangle inkRect; + PangoRectangle logicalRect; + pango_layout_get_pixel_extents(layout, &inkRect, &logicalRect); + + int stockWidth = logicalRect.x + logicalRect.width; + int stockHeight = logicalRect.y + logicalRect.height; + + pango_layout_set_height(layout, rect.height()*PANGO_SCALE); + + // Position flags + if (textFlags & TQt::AlignAuto) { + // FIXME + } + if (textFlags & TQt::AlignLeft) { + pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); + } + if (textFlags & TQt::AlignRight) { + pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); + } + if (textFlags & TQt::AlignHCenter) { + pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); + } + if (textFlags & TQt::AlignJustify) { + // FIXME + } + if (textFlags & TQt::AlignTop) { + fudgedOffsetY = 0; + } + if (textFlags & TQt::AlignBottom) { + fudgedOffsetY = (rect.height()-stockHeight); + } + if (textFlags & TQt::AlignVCenter) { + fudgedOffsetY = ((rect.height()-stockHeight)/2); + } + + cairo_new_path(m_painter); + cairo_move_to(m_painter, rect.x(), rect.y() + fudgedOffsetY); + 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); + } + cairo_reset_clip(m_painter); + + g_object_unref(layout); + + transferIntermediateSurface(); +} + void TQt3CairoPaintDevice::setCairoTransformations() { cairo_matrix_t combinedMatrix; cairo_matrix_t tempMatrix; @@ -994,33 +1089,43 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p ) 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); + drawText(pt, p[0].rect->x()+CAIRO_PIXEL_OFFSET, p[0].rect->y()+CAIRO_PIXEL_OFFSET, string); } cairo_restore(m_painter); } break; -#if 0 case PdcDrawTextFormatted: - // NOTE - // Unlike PdcDrawText and PdcDrawText2, PdcDrawTextFormatted and PdcDrawText2Formatted do NOT use the baseline as the Y position coordinate! - m_qt4painter->drawText( qt4rect, qt4formattedtextflags, qt4string ); + if (m_painter) { + cairo_save(m_painter); + if (p) { + TQRect rect = *p[0].rect; + TQString string = *p[2].str; + drawTextInRect(pt, rect, p[1].ival, string); + } + cairo_restore(m_painter); + } break; -#endif case PdcDrawText2: 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); + drawText(pt, p[0].rect->x()+CAIRO_PIXEL_OFFSET, p[0].rect->y()+CAIRO_PIXEL_OFFSET, string); } cairo_restore(m_painter); } break; -#if 0 case PdcDrawText2Formatted: - m_qt4painter->drawText( qt4rect, qt4formattedtextflags, qt4string ); + if (m_painter) { + cairo_save(m_painter); + if (p) { + TQRect rect = *p[0].rect; + TQString string = *p[2].str; + drawTextInRect(pt, rect, p[1].ival, string); + } + cairo_restore(m_painter); + } break; -#endif case PdcDrawPixmap: if (m_painter) { cairo_save(m_painter); @@ -1036,19 +1141,22 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p ) transferIntermediateSurface(); } break; -#if 0 - case PdcDrawImage: { - TQImage image; - if ( d->formatMajor < 4 ) { - s >> p >> image; - painter->drawImage( p, image ); - } else { - s >> r >> image; - painter->drawImage( r, image ); - } + case PdcDrawImage: + if (m_painter) { + cairo_save(m_painter); + if (p) { + TQRect rect = *p[0].rect; + TQImage image = *p[1].image; + cairo_surface_t* sourceSurface = TQImageToCairoSurface(image); + cairo_rectangle(m_painter, rect.x(), rect.y(), rect.width(), rect.height()); + cairo_set_source_surface(m_painter, sourceSurface, rect.x(), rect.y()); + cairo_fill(m_painter); + cairo_surface_destroy(sourceSurface); + } + cairo_restore(m_painter); + transferIntermediateSurface(); } break; -#endif case PdcBegin: if (!m_painter) { m_bgColor = TQColor(0,0,0); @@ -1065,6 +1173,7 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p ) cairo_matrix_init_identity(&m_viewportMatrix); setCairoTransformations(); m_clipRegion = TQImage(); + m_clipRegionEnabled = false; } break; case PdcEnd: @@ -1278,7 +1387,6 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p ) } break; #if 0 -#if 0 #ifndef QT_NO_TRANSFORMATIONS case PdcSaveWMatrix: painter->saveWorldMatrix(); @@ -1289,9 +1397,10 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p ) #endif #endif case PdcSetClip: - m_qt4painter->setClipping( p[0].ival ); + if ((p) && (m_painter)) { + m_clipRegionEnabled = p[0].ival; + } break; -#endif case PdcSetClipRegion: if ((p) && (m_painter)) { // SLOW @@ -1306,9 +1415,11 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p ) m_clipRegion.setPixel(x, y, (p[0].rgn->contains(point))?0xffffffff:0x00000000); } } + m_clipRegionEnabled = true; } else { m_clipRegion = TQImage(); + m_clipRegionEnabled = false; } } break; diff --git a/tdegtk/tqtcairopainter.h b/tdegtk/tqtcairopainter.h index ef3dbac..9332128 100644 --- a/tdegtk/tqtcairopainter.h +++ b/tdegtk/tqtcairopainter.h @@ -62,7 +62,8 @@ class Q_EXPORT TQt3CairoPaintDevice : public TQPaintDevice // picture class void drawChord(int x, int y, int w, int h, int a, int alen); void pangoSetupTextPath(PangoLayout *layout, const char* text); - void drawText(TQPainter *p, int x, int y, const TQString &str, int pos, int len, TQPainter::TextDirection dir, bool baseline=TRUE); + void drawText(TQPainter *p, int x, int y, const TQString &str); + void drawTextInRect(TQPainter *p, TQRect rect, int textFlags, const TQString &str); void setCairoTransformations(); @@ -83,6 +84,7 @@ class Q_EXPORT TQt3CairoPaintDevice : public TQPaintDevice // picture class TQPoint m_brushOrigin; TQFont m_font; TQImage m_clipRegion; + bool m_clipRegionEnabled; }; #endif // TDEQT4PAINTER_H diff --git a/tests/test-painter.cpp b/tests/test-painter.cpp index f458e26..fe1939f 100644 --- a/tests/test-painter.cpp +++ b/tests/test-painter.cpp @@ -167,6 +167,12 @@ void runTests(TQPaintDevice* pd) { p.drawPixmap(200, 10, pixmap, 0, 0, -1, -1); } + // Image tests + { + TQImage image("open.png"); + p.drawImage(350, 10, image, 0, 0, -1, -1); + } + // Font tests { p.setPen(TQColor(0,128,255)); @@ -195,8 +201,12 @@ void runTests(TQPaintDevice* pd) { } } - p.setPen(TQColor(255,128,0)); - p.drawText( TQRect(250, 250, 250, 250), 0, TQString("TQt3 renders via Cairo!") ); + //p.setPen(TQColor(255,128,0)); + //p.drawText( TQRect(250, 250, 250, 150), TQt::BreakAnywhere, TQString("TQt3 renders via Cairo!") ); + + //p.setPen(TQColor(255,0,128)); + //p.drawText( TQRect(0, 250, 250, 150), TQt::BreakAnywhere | TQt::AlignCenter, TQString("TQt3 renders via Cairo!") ); + //p.drawText( TQRect(0, 250, 250, 150), TQt::BreakAnywhere | TQt::AlignHCenter | TQt::AlignBottom, TQString("TQt3 renders via Cairo!") ); } // Clipping tests