TDE graphics utilities
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

kpselection.cpp 37KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. /*
  2. Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions
  6. are met:
  7. 1. Redistributions of source code must retain the above copyright
  8. notice, this list of conditions and the following disclaimer.
  9. 2. Redistributions in binary form must reproduce the above copyright
  10. notice, this list of conditions and the following disclaimer in the
  11. documentation and/or other materials provided with the distribution.
  12. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  13. IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  14. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  15. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  16. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  17. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  18. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  19. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  20. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  21. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22. */
  23. #define DEBUG_KP_SELECTION 0
  24. #include <kpselection.h>
  25. #include <tqfont.h>
  26. #include <tqimage.h>
  27. #include <tqpainter.h>
  28. #include <tqwmatrix.h>
  29. #include <kdebug.h>
  30. #include <tdelocale.h>
  31. #include <kpcolorsimilaritydialog.h>
  32. #include <kpdefs.h>
  33. #include <kppixmapfx.h>
  34. #include <kptool.h>
  35. kpSelection::kpSelection (const kpSelectionTransparency &transparency)
  36. : TQObject (),
  37. m_type (kpSelection::Rectangle),
  38. m_pixmap (0)
  39. {
  40. setTransparency (transparency);
  41. }
  42. kpSelection::kpSelection (Type type, const TQRect &rect, const TQPixmap &pixmap,
  43. const kpSelectionTransparency &transparency)
  44. : TQObject (),
  45. m_type (type),
  46. m_rect (rect)
  47. {
  48. calculatePoints ();
  49. m_pixmap = pixmap.isNull () ? 0 : new TQPixmap (pixmap);
  50. setTransparency (transparency);
  51. }
  52. kpSelection::kpSelection (Type type, const TQRect &rect, const kpSelectionTransparency &transparency)
  53. : TQObject (),
  54. m_type (type),
  55. m_rect (rect),
  56. m_pixmap (0)
  57. {
  58. calculatePoints ();
  59. setTransparency (transparency);
  60. }
  61. kpSelection::kpSelection (const TQRect &rect,
  62. const TQValueVector <TQString> &textLines_,
  63. const kpTextStyle &textStyle_)
  64. : TQObject (),
  65. m_type (Text),
  66. m_rect (rect),
  67. m_pixmap (0),
  68. m_textStyle (textStyle_)
  69. {
  70. calculatePoints ();
  71. setTextLines (textLines_);
  72. }
  73. kpSelection::kpSelection (const TQPointArray &points, const TQPixmap &pixmap,
  74. const kpSelectionTransparency &transparency)
  75. : TQObject (),
  76. m_type (Points),
  77. m_rect (points.boundingRect ()),
  78. m_points (points)
  79. {
  80. m_pixmap = pixmap.isNull () ? 0 : new TQPixmap (pixmap);
  81. m_points.detach ();
  82. setTransparency (transparency);
  83. }
  84. kpSelection::kpSelection (const TQPointArray &points, const kpSelectionTransparency &transparency)
  85. : TQObject (),
  86. m_type (Points),
  87. m_rect (points.boundingRect ()),
  88. m_points (points),
  89. m_pixmap (0)
  90. {
  91. m_points.detach ();
  92. setTransparency (transparency);
  93. }
  94. kpSelection::kpSelection (const kpSelection &rhs)
  95. : TQObject (),
  96. m_type (rhs.m_type),
  97. m_rect (rhs.m_rect),
  98. m_points (rhs.m_points),
  99. m_pixmap (rhs.m_pixmap ? new TQPixmap (*rhs.m_pixmap) : 0),
  100. m_textLines (rhs.m_textLines),
  101. m_textStyle (rhs.m_textStyle),
  102. m_transparency (rhs.m_transparency),
  103. m_transparencyMask (rhs.m_transparencyMask)
  104. {
  105. m_points.detach ();
  106. }
  107. kpSelection &kpSelection::operator= (const kpSelection &rhs)
  108. {
  109. if (this == &rhs)
  110. return *this;
  111. m_type = rhs.m_type;
  112. m_rect = rhs.m_rect;
  113. m_points = rhs.m_points;
  114. m_points.detach ();
  115. delete m_pixmap;
  116. m_pixmap = rhs.m_pixmap ? new TQPixmap (*rhs.m_pixmap) : 0;
  117. m_textLines = rhs.m_textLines;
  118. m_textStyle = rhs.m_textStyle;
  119. m_transparency = rhs.m_transparency;
  120. m_transparencyMask = rhs.m_transparencyMask;
  121. return *this;
  122. }
  123. // friend
  124. TQDataStream &operator<< (TQDataStream &stream, const kpSelection &selection)
  125. {
  126. #if DEBUG_KP_SELECTION && 1
  127. kdDebug () << "kpSelection::operator<<(sel: rect=" << selection.boundingRect ()
  128. << " pixmap rect=" << (selection.pixmap () ? selection.pixmap ()->rect () : TQRect ())
  129. << endl;
  130. #endif
  131. stream << int (selection.m_type);
  132. stream << selection.m_rect;
  133. stream << selection.m_points;
  134. #if DEBUG_KP_SELECTION && 1
  135. kdDebug () << "\twrote type=" << int (selection.m_type) << " rect=" << selection.m_rect
  136. << " and points" << endl;
  137. #endif
  138. // TODO: need for text?
  139. // For now we just use TQTextDrag for Text Selections so this point is mute.
  140. if (selection.m_pixmap)
  141. {
  142. const TQImage image = kpPixmapFX::convertToImage (*selection.m_pixmap);
  143. #if DEBUG_KP_SELECTION && 1
  144. kdDebug () << "\twrote image rect=" << image.rect () << endl;
  145. #endif
  146. stream << image;
  147. }
  148. else
  149. {
  150. #if DEBUG_KP_SELECTION && 1
  151. kdDebug () << "\twrote no image because no pixmap" << endl;
  152. #endif
  153. stream << TQImage ();
  154. }
  155. //stream << selection.m_textLines;
  156. //stream << selection.m_textStyle;
  157. return stream;
  158. }
  159. // friend
  160. TQDataStream &operator>> (TQDataStream &stream, kpSelection &selection)
  161. {
  162. selection.readFromStream (stream);
  163. return stream;
  164. }
  165. // public
  166. // TODO: KolourPaint has not been tested against invalid or malicious
  167. // clipboard data [Bug #28].
  168. void kpSelection::readFromStream (TQDataStream &stream,
  169. const kpPixmapFX::WarnAboutLossInfo &wali)
  170. {
  171. #if DEBUG_KP_SELECTION && 1
  172. kdDebug () << "kpSelection::readFromStream()" << endl;
  173. #endif
  174. int typeAsInt;
  175. stream >> typeAsInt;
  176. m_type = kpSelection::Type (typeAsInt);
  177. #if DEBUG_KP_SELECTION && 1
  178. kdDebug () << "\ttype=" << typeAsInt << endl;
  179. #endif
  180. stream >> m_rect;
  181. stream >> m_points;
  182. m_points.detach ();
  183. #if DEBUG_KP_SELECTION && 1
  184. kdDebug () << "\trect=" << m_rect << endl;
  185. //kdDebug () << "\tpoints=" << m_points << endl;
  186. #endif
  187. TQImage image;
  188. stream >> image;
  189. delete m_pixmap;
  190. if (!image.isNull ())
  191. m_pixmap = new TQPixmap (kpPixmapFX::convertToPixmap (image, false/*no dither*/, wali));
  192. else
  193. m_pixmap = 0;
  194. #if DEBUG_KP_SELECTION && 1
  195. kdDebug () << "\timage: w=" << image.width () << " h=" << image.height ()
  196. << " depth=" << image.depth () << endl;
  197. if (m_pixmap)
  198. {
  199. kdDebug () << "\tpixmap: w=" << m_pixmap->width () << " h=" << m_pixmap->height ()
  200. << endl;
  201. }
  202. else
  203. {
  204. kdDebug () << "\tpixmap: none" << endl;
  205. }
  206. #endif
  207. //stream >> m_textLines;
  208. //stream >> m_textStyle;
  209. }
  210. kpSelection::~kpSelection ()
  211. {
  212. delete m_pixmap; m_pixmap = 0;
  213. }
  214. // private
  215. void kpSelection::calculatePoints ()
  216. {
  217. if (m_type == kpSelection::Points)
  218. return;
  219. if (m_type == kpSelection::Ellipse)
  220. {
  221. m_points.makeEllipse (m_rect.x (), m_rect.y (),
  222. m_rect.width (), m_rect.height ());
  223. return;
  224. }
  225. if (m_type == kpSelection::Rectangle || m_type == kpSelection::Text)
  226. {
  227. // OPT: not space optimal - redoes corners
  228. m_points.resize (m_rect.width () * 2 + m_rect.height () * 2);
  229. int pointsUpto = 0;
  230. // top
  231. for (int x = 0; x < m_rect.width (); x++)
  232. m_points [pointsUpto++] = TQPoint (m_rect.x () + x, m_rect.top ());
  233. // right
  234. for (int y = 0; y < m_rect.height (); y++)
  235. m_points [pointsUpto++] = TQPoint (m_rect.right (), m_rect.y () + y);
  236. // bottom
  237. for (int x = m_rect.width () - 1; x >= 0; x--)
  238. m_points [pointsUpto++] = TQPoint (m_rect.x () + x, m_rect.bottom ());
  239. // left
  240. for (int y = m_rect.height () - 1; y >= 0; y--)
  241. m_points [pointsUpto++] = TQPoint (m_rect.left (), m_rect.y () + y);
  242. return;
  243. }
  244. kdError () << "kpSelection::calculatePoints() with unknown type" << endl;
  245. return;
  246. }
  247. // public
  248. kpSelection::Type kpSelection::type () const
  249. {
  250. return m_type;
  251. }
  252. // public
  253. bool kpSelection::isRectangular () const
  254. {
  255. return (m_type == Rectangle || m_type == Text);
  256. }
  257. // public
  258. bool kpSelection::isText () const
  259. {
  260. return (m_type == Text);
  261. }
  262. // public
  263. TQString kpSelection::name () const
  264. {
  265. if (m_type == Text)
  266. return i18n ("Text");
  267. return i18n ("Selection");
  268. }
  269. // public
  270. int kpSelection::size () const
  271. {
  272. return kpPixmapFX::pointArraySize (m_points) +
  273. kpPixmapFX::pixmapSize (m_pixmap) +
  274. kpPixmapFX::stringSize (text ()) +
  275. kpPixmapFX::pixmapSize (m_transparencyMask);
  276. }
  277. // public
  278. TQBitmap kpSelection::maskForOwnType (bool nullForRectangular) const
  279. {
  280. if (!m_rect.isValid ())
  281. {
  282. kdError () << "kpSelection::maskForOwnType() boundingRect invalid" << endl;
  283. return TQBitmap ();
  284. }
  285. if (isRectangular ())
  286. {
  287. if (nullForRectangular)
  288. return TQBitmap ();
  289. TQBitmap maskBitmap (m_rect.width (), m_rect.height ());
  290. maskBitmap.fill (TQt::color1/*opaque*/);
  291. return maskBitmap;
  292. }
  293. TQBitmap maskBitmap (m_rect.width (), m_rect.height ());
  294. maskBitmap.fill (TQt::color0/*transparent*/);
  295. TQPainter painter;
  296. painter.begin (&maskBitmap);
  297. painter.setPen (TQt::color1)/*opaque*/;
  298. painter.setBrush (TQt::color1/*opaque*/);
  299. if (m_type == kpSelection::Ellipse)
  300. painter.drawEllipse (0, 0, m_rect.width (), m_rect.height ());
  301. else if (m_type == kpSelection::Points)
  302. {
  303. TQPointArray points = m_points;
  304. points.detach ();
  305. points.translate (-m_rect.x (), -m_rect.y ());
  306. painter.drawPolygon (points, false/*even-odd algo*/);
  307. }
  308. painter.end ();
  309. return maskBitmap;
  310. }
  311. // public
  312. TQPoint kpSelection::topLeft () const
  313. {
  314. return m_rect.topLeft ();
  315. }
  316. // public
  317. TQPoint kpSelection::point () const
  318. {
  319. return m_rect.topLeft ();
  320. }
  321. // public
  322. int kpSelection::x () const
  323. {
  324. return m_rect.x ();
  325. }
  326. // public
  327. int kpSelection::y () const
  328. {
  329. return m_rect.y ();
  330. }
  331. // public
  332. void kpSelection::moveBy (int dx, int dy)
  333. {
  334. #if DEBUG_KP_SELECTION && 1
  335. kdDebug () << "kpSelection::moveBy(" << dx << "," << dy << ")" << endl;
  336. #endif
  337. if (dx == 0 && dy == 0)
  338. return;
  339. TQRect oldRect = boundingRect ();
  340. #if DEBUG_KP_SELECTION && 1
  341. kdDebug () << "\toldRect=" << oldRect << endl;
  342. #endif
  343. m_rect.moveBy (dx, dy);
  344. m_points.translate (dx, dy);
  345. #if DEBUG_KP_SELECTION && 1
  346. kdDebug () << "\tnewRect=" << m_rect << endl;
  347. #endif
  348. emit changed (oldRect);
  349. emit changed (boundingRect ());
  350. }
  351. // public
  352. void kpSelection::moveTo (int dx, int dy)
  353. {
  354. moveTo (TQPoint (dx, dy));
  355. }
  356. // public
  357. void kpSelection::moveTo (const TQPoint &topLeftPoint)
  358. {
  359. #if DEBUG_KP_SELECTION && 1
  360. kdDebug () << "kpSelection::moveTo(" << topLeftPoint << ")" << endl;
  361. #endif
  362. TQRect oldBoundingRect = boundingRect ();
  363. #if DEBUG_KP_SELECTION && 1
  364. kdDebug () << "\toldBoundingRect=" << oldBoundingRect << endl;
  365. #endif
  366. if (topLeftPoint == oldBoundingRect.topLeft ())
  367. return;
  368. TQPoint delta (topLeftPoint - oldBoundingRect.topLeft ());
  369. moveBy (delta.x (), delta.y ());
  370. }
  371. // public
  372. TQPointArray kpSelection::points () const
  373. {
  374. return m_points;
  375. }
  376. // public
  377. TQPointArray kpSelection::pointArray () const
  378. {
  379. return m_points;
  380. }
  381. // public
  382. TQRect kpSelection::boundingRect () const
  383. {
  384. return m_rect;
  385. }
  386. // public
  387. int kpSelection::width () const
  388. {
  389. return boundingRect ().width ();
  390. }
  391. // public
  392. int kpSelection::height () const
  393. {
  394. return boundingRect ().height ();
  395. }
  396. // public
  397. bool kpSelection::contains (const TQPoint &point) const
  398. {
  399. TQRect rect = boundingRect ();
  400. #if DEBUG_KP_SELECTION && 1
  401. kdDebug () << "kpSelection::contains(" << point
  402. << ") rect==" << rect
  403. << " #points=" << m_points.size ()
  404. << endl;
  405. #endif
  406. if (!rect.contains (point))
  407. return false;
  408. // OPT: TQRegion is probably incredibly slow - cache
  409. // We can't use the m_pixmap (if avail) and get the transparency of
  410. // the pixel at that point as it may be transparent but still within the
  411. // border
  412. switch (m_type)
  413. {
  414. case kpSelection::Rectangle:
  415. case kpSelection::Text:
  416. return true;
  417. case kpSelection::Ellipse:
  418. return TQRegion (m_rect, TQRegion::Ellipse).contains (point);
  419. case kpSelection::Points:
  420. // TODO: make this always include the border
  421. // (draw up a rect sel in this mode to see what I mean)
  422. return TQRegion (m_points, false/*even-odd algo*/).contains (point);
  423. default:
  424. return false;
  425. }
  426. }
  427. // public
  428. bool kpSelection::contains (int x, int y)
  429. {
  430. return contains (TQPoint (x, y));
  431. }
  432. // public
  433. TQPixmap *kpSelection::pixmap () const
  434. {
  435. return m_pixmap;
  436. }
  437. // public
  438. void kpSelection::setPixmap (const TQPixmap &pixmap)
  439. {
  440. delete m_pixmap;
  441. // TODO: If isText(), setting pixmap() to 0 is unexpected (implies
  442. // it's a border, not a text box) but saves memory when using
  443. // that kpSelection::setPixmap (TQPixmap ()) hack.
  444. m_pixmap = pixmap.isNull () ? 0 : new TQPixmap (pixmap);
  445. TQRect changedRect = boundingRect ();
  446. if (m_pixmap)
  447. {
  448. const bool changedSize = (m_pixmap->width () != m_rect.width () ||
  449. m_pixmap->height () != m_rect.height ());
  450. const bool changedFromText = (m_type == Text);
  451. if (changedSize || changedFromText)
  452. {
  453. if (changedSize)
  454. {
  455. kdError () << "kpSelection::setPixmap() changes the size of the selection!"
  456. << " old:"
  457. << " w=" << m_rect.width ()
  458. << " h=" << m_rect.height ()
  459. << " new:"
  460. << " w=" << m_pixmap->width ()
  461. << " h=" << m_pixmap->height ()
  462. << endl;
  463. }
  464. if (changedFromText)
  465. {
  466. kdError () << "kpSelection::setPixmap() changed from text" << endl;
  467. }
  468. m_type = kpSelection::Rectangle;
  469. m_rect = TQRect (m_rect.x (), m_rect.y (),
  470. m_pixmap->width (), m_pixmap->height ());
  471. calculatePoints ();
  472. m_textLines = TQValueVector <TQString> ();
  473. changedRect = changedRect.unite (boundingRect ());
  474. }
  475. }
  476. calculateTransparencyMask ();
  477. emit changed (changedRect);
  478. }
  479. // public
  480. bool kpSelection::usesBackgroundPixmapToPaint () const
  481. {
  482. // Opaque text with transparent background needs to antialias with
  483. // doc pixmap below it.
  484. return (isText () &&
  485. m_textStyle.foregroundColor ().isOpaque () &&
  486. m_textStyle.effectiveBackgroundColor ().isTransparent ());
  487. }
  488. static int mostContrastingValue (int val)
  489. {
  490. if (val <= 127)
  491. return 255;
  492. else
  493. return 0;
  494. }
  495. static TQRgb mostContrastingRGB (TQRgb val)
  496. {
  497. return tqRgba (mostContrastingValue (tqRed (val)),
  498. mostContrastingValue (tqGreen (val)),
  499. mostContrastingValue (tqBlue (val)),
  500. mostContrastingValue (tqAlpha (val)));
  501. }
  502. // private
  503. static void drawTextLines (TQPainter *painter, TQPainter *maskPainter,
  504. const TQRect &rect,
  505. const TQValueVector <TQString> &textLines)
  506. {
  507. if (!painter->clipRegion ().isEmpty () || !maskPainter->clipRegion ().isEmpty ())
  508. {
  509. // TODO: fix esp. before making method public
  510. kdError () << "kpselection.cpp:drawTextLines() can't deal with existing painter clip regions" << endl;
  511. return;
  512. }
  513. #define PAINTER_CALL(cmd) \
  514. { \
  515. if (painter->isActive ()) \
  516. painter->cmd; \
  517. \
  518. if (maskPainter->isActive ()) \
  519. maskPainter->cmd; \
  520. }
  521. // Can't do this because the line heights become
  522. // >TQFontMetrics::height() if you type Chinese characters (!) and then
  523. // the cursor gets out of sync.
  524. // PAINTER_CALL (drawText (rect, 0/*flags*/, text ()));
  525. #if 0
  526. const TQFontMetrics fontMetrics (painter->fontMetrics ());
  527. kdDebug () << "height=" << fontMetrics.height ()
  528. << " leading=" << fontMetrics.leading ()
  529. << " ascent=" << fontMetrics.ascent ()
  530. << " descent=" << fontMetrics.descent ()
  531. << " lineSpacing=" << fontMetrics.lineSpacing ()
  532. << endl;
  533. #endif
  534. PAINTER_CALL (setClipRect (rect, TQPainter::CoordPainter/*transform*/));
  535. int baseLine = rect.y () + painter->fontMetrics ().ascent ();
  536. for (TQValueVector <TQString>::const_iterator it = textLines.begin ();
  537. it != textLines.end ();
  538. it++)
  539. {
  540. PAINTER_CALL (drawText (rect.x (), baseLine, *it));
  541. baseLine += painter->fontMetrics ().lineSpacing ();
  542. }
  543. #undef PAINTER_CALL
  544. }
  545. // private
  546. void kpSelection::paintOpaqueText (TQPixmap *destPixmap, const TQRect &docRect) const
  547. {
  548. if (!isText () || !m_textStyle.foregroundColor ().isOpaque ())
  549. return;
  550. const TQRect modifyingRect = docRect.intersect (boundingRect ());
  551. if (modifyingRect.isEmpty ())
  552. return;
  553. TQBitmap destPixmapMask;
  554. TQPainter destPixmapPainter, destPixmapMaskPainter;
  555. if (destPixmap->mask ())
  556. {
  557. if (m_textStyle.effectiveBackgroundColor ().isTransparent ())
  558. {
  559. TQRect modifyingRectRelPixmap = modifyingRect;
  560. modifyingRectRelPixmap.moveBy (-docRect.x (), -docRect.y ());
  561. // Set the RGB of transparent pixels to foreground colour to avoid
  562. // anti-aliasing the foreground coloured text with undefined RGBs.
  563. kpPixmapFX::setPixmapAt (destPixmap,
  564. modifyingRectRelPixmap,
  565. kpPixmapFX::pixmapWithDefinedTransparentPixels (
  566. kpPixmapFX::getPixmapAt (*destPixmap, modifyingRectRelPixmap),
  567. m_textStyle.foregroundColor ().toTQColor ()));
  568. }
  569. destPixmapMask = *destPixmap->mask ();
  570. destPixmapMaskPainter.begin (&destPixmapMask);
  571. destPixmapMaskPainter.translate (-docRect.x (), -docRect.y ());
  572. destPixmapMaskPainter.setPen (TQt::color1/*opaque*/);
  573. destPixmapMaskPainter.setFont (m_textStyle.font ());
  574. }
  575. destPixmapPainter.begin (destPixmap);
  576. destPixmapPainter.translate (-docRect.x (), -docRect.y ());
  577. destPixmapPainter.setPen (m_textStyle.foregroundColor ().toTQColor ());
  578. destPixmapPainter.setFont (m_textStyle.font ());
  579. if (m_textStyle.effectiveBackgroundColor ().isOpaque ())
  580. {
  581. destPixmapPainter.fillRect (
  582. boundingRect (),
  583. m_textStyle.effectiveBackgroundColor ().toTQColor ());
  584. if (destPixmapMaskPainter.isActive ())
  585. {
  586. destPixmapMaskPainter.fillRect (
  587. boundingRect (),
  588. TQt::color1/*opaque*/);
  589. }
  590. }
  591. ::drawTextLines (&destPixmapPainter, &destPixmapMaskPainter,
  592. textAreaRect (),
  593. textLines ());
  594. if (destPixmapPainter.isActive ())
  595. destPixmapPainter.end ();
  596. if (destPixmapMaskPainter.isActive ())
  597. destPixmapMaskPainter.end ();
  598. if (!destPixmapMask.isNull ())
  599. destPixmap->setMask (destPixmapMask);
  600. }
  601. // private
  602. TQPixmap kpSelection::transparentForegroundTextPixmap () const
  603. {
  604. if (!isText () || !m_textStyle.foregroundColor ().isTransparent ())
  605. return TQPixmap ();
  606. TQPixmap pixmap (m_rect.width (), m_rect.height ());
  607. TQBitmap pixmapMask (m_rect.width (), m_rect.height ());
  608. // Iron out stupid case first
  609. if (m_textStyle.effectiveBackgroundColor ().isTransparent ())
  610. {
  611. pixmapMask.fill (TQt::color0/*transparent*/);
  612. pixmap.setMask (pixmapMask);
  613. return pixmap;
  614. }
  615. // -- Foreground transparent, background opaque --
  616. TQFont font = m_textStyle.font ();
  617. // TODO: why doesn't "font.setStyleStrategy (TQFont::NoAntialias);"
  618. // let us avoid the hack below?
  619. TQPainter pixmapPainter, pixmapMaskPainter;
  620. pixmap.fill (m_textStyle.effectiveBackgroundColor ().toTQColor ());
  621. pixmapPainter.begin (&pixmap);
  622. // HACK: Transparent foreground colour + antialiased fonts don't
  623. // work - they don't seem to be able to draw in
  624. // TQt::color0/*transparent*/ (but TQt::color1 seems Ok).
  625. // So we draw in a contrasting color to the background so that
  626. // we can identify the transparent pixels for manually creating
  627. // the mask.
  628. pixmapPainter.setPen (
  629. TQColor (mostContrastingRGB (m_textStyle.effectiveBackgroundColor ().toTQRgb () & TQRGB_MASK)));
  630. pixmapPainter.setFont (font);
  631. pixmapMask.fill (TQt::color1/*opaque*/);
  632. pixmapMaskPainter.begin (&pixmapMask);
  633. pixmapMaskPainter.setPen (TQt::color0/*transparent*/);
  634. pixmapMaskPainter.setFont (font);
  635. TQRect rect (textAreaRect ());
  636. rect.moveBy (-m_rect.x (), -m_rect.y ());
  637. ::drawTextLines (&pixmapPainter, &pixmapMaskPainter,
  638. rect,
  639. textLines ());
  640. if (pixmapPainter.isActive ())
  641. pixmapPainter.end ();
  642. if (pixmapMaskPainter.isActive ())
  643. pixmapMaskPainter.end ();
  644. #if DEBUG_KP_SELECTION
  645. kdDebug () << "\tinvoking foreground transparency hack" << endl;
  646. #endif
  647. TQImage image = kpPixmapFX::convertToImage (pixmap);
  648. TQRgb backgroundRGB = image.pixel (0, 0); // on textBorderSize()
  649. pixmapMaskPainter.begin (&pixmapMask);
  650. for (int y = 0; y < image.height (); y++)
  651. {
  652. for (int x = 0; x < image.width (); x++)
  653. {
  654. if (image.pixel (x, y) == backgroundRGB)
  655. pixmapMaskPainter.setPen (TQt::color1/*opaque*/);
  656. else
  657. pixmapMaskPainter.setPen (TQt::color0/*transparent*/);
  658. pixmapMaskPainter.drawPoint (x, y);
  659. }
  660. }
  661. pixmapMaskPainter.end ();
  662. if (!pixmapMask.isNull ())
  663. pixmap.setMask (pixmapMask);
  664. return pixmap;
  665. }
  666. // public
  667. void kpSelection::paint (TQPixmap *destPixmap, const TQRect &docRect) const
  668. {
  669. if (!isText ())
  670. {
  671. if (pixmap () && !pixmap ()->isNull ())
  672. {
  673. kpPixmapFX::paintPixmapAt (destPixmap,
  674. topLeft () - docRect.topLeft (),
  675. transparentPixmap ());
  676. }
  677. }
  678. else
  679. {
  680. #if DEBUG_KP_SELECTION
  681. kdDebug () << "kpSelection::paint() textStyle: fcol="
  682. << (int *) m_textStyle.foregroundColor ().toTQRgb ()
  683. << " bcol="
  684. << (int *) m_textStyle.effectiveBackgroundColor ().toTQRgb ()
  685. << endl;
  686. #endif
  687. if (m_textStyle.foregroundColor ().isOpaque ())
  688. {
  689. // (may have to antialias with background so don't use m_pixmap)
  690. paintOpaqueText (destPixmap, docRect);
  691. }
  692. else
  693. {
  694. if (!m_pixmap)
  695. {
  696. kdError () << "kpSelection::paint() without m_pixmap?" << endl;
  697. return;
  698. }
  699. // (transparent foreground slow to render, no antialiasing
  700. // so use m_pixmap cache)
  701. kpPixmapFX::paintPixmapAt (destPixmap,
  702. topLeft () - docRect.topLeft (),
  703. *m_pixmap);
  704. }
  705. }
  706. }
  707. // private
  708. void kpSelection::calculateTextPixmap ()
  709. {
  710. if (!isText ())
  711. {
  712. kdError () << "kpSelection::calculateTextPixmap() not text sel"
  713. << endl;
  714. return;
  715. }
  716. delete m_pixmap;
  717. if (m_textStyle.foregroundColor().isOpaque ())
  718. {
  719. m_pixmap = new TQPixmap (m_rect.width (), m_rect.height ());
  720. if (usesBackgroundPixmapToPaint ())
  721. kpPixmapFX::fill (m_pixmap, kpColor::transparent);
  722. paintOpaqueText (m_pixmap, m_rect);
  723. }
  724. else
  725. {
  726. m_pixmap = new TQPixmap (transparentForegroundTextPixmap ());
  727. }
  728. }
  729. // public static
  730. TQString kpSelection::textForTextLines (const TQValueVector <TQString> &textLines_)
  731. {
  732. if (textLines_.isEmpty ())
  733. return TQString();
  734. TQString bigString = textLines_ [0];
  735. for (TQValueVector <TQString>::const_iterator it = textLines_.begin () + 1;
  736. it != textLines_.end ();
  737. it++)
  738. {
  739. bigString += TQString::fromLatin1 ("\n");
  740. bigString += (*it);
  741. }
  742. return bigString;
  743. }
  744. // public
  745. TQString kpSelection::text () const
  746. {
  747. if (!isText ())
  748. {
  749. return TQString();
  750. }
  751. return textForTextLines (m_textLines);
  752. }
  753. // public
  754. TQValueVector <TQString> kpSelection::textLines () const
  755. {
  756. if (!isText ())
  757. {
  758. kdError () << "kpSelection::textLines() not a text selection" << endl;
  759. return TQValueVector <TQString> ();
  760. }
  761. return m_textLines;
  762. }
  763. // public
  764. void kpSelection::setTextLines (const TQValueVector <TQString> &textLines_)
  765. {
  766. if (!isText ())
  767. {
  768. kdError () << "kpSelection::setTextLines() not a text selection" << endl;
  769. return;
  770. }
  771. m_textLines = textLines_;
  772. if (m_textLines.isEmpty ())
  773. {
  774. kdError () << "kpSelection::setTextLines() passed no lines" << endl;
  775. m_textLines.push_back (TQString());
  776. }
  777. calculateTextPixmap ();
  778. emit changed (boundingRect ());
  779. }
  780. // public static
  781. int kpSelection::textBorderSize ()
  782. {
  783. return 1;
  784. }
  785. // public
  786. TQRect kpSelection::textAreaRect () const
  787. {
  788. if (!isText ())
  789. {
  790. kdError () << "kpSelection::textAreaRect() not a text selection" << endl;
  791. return TQRect ();
  792. }
  793. return TQRect (m_rect.x () + textBorderSize (),
  794. m_rect.y () + textBorderSize (),
  795. m_rect.width () - textBorderSize () * 2,
  796. m_rect.height () - textBorderSize () * 2);
  797. }
  798. // public
  799. bool kpSelection::pointIsInTextBorderArea (const TQPoint &globalPoint) const
  800. {
  801. if (!isText ())
  802. {
  803. kdError () << "kpSelection::pointIsInTextBorderArea() not a text selection" << endl;
  804. return false;
  805. }
  806. return (m_rect.contains (globalPoint) && !pointIsInTextArea (globalPoint));
  807. }
  808. // public
  809. bool kpSelection::pointIsInTextArea (const TQPoint &globalPoint) const
  810. {
  811. if (!isText ())
  812. {
  813. kdError () << "kpSelection::pointIsInTextArea() not a text selection" << endl;
  814. return false;
  815. }
  816. return textAreaRect ().contains (globalPoint);
  817. }
  818. // public
  819. void kpSelection::textResize (int width, int height)
  820. {
  821. if (!isText ())
  822. {
  823. kdError () << "kpSelection::textResize() not a text selection" << endl;
  824. return;
  825. }
  826. TQRect oldRect = m_rect;
  827. m_rect = TQRect (oldRect.x (), oldRect.y (), width, height);
  828. calculatePoints ();
  829. calculateTextPixmap ();
  830. emit changed (m_rect.unite (oldRect));
  831. }
  832. // public static
  833. int kpSelection::minimumWidthForTextStyle (const kpTextStyle &)
  834. {
  835. return (kpSelection::textBorderSize () * 2 + 5);
  836. }
  837. // public static
  838. int kpSelection::minimumHeightForTextStyle (const kpTextStyle &)
  839. {
  840. return (kpSelection::textBorderSize () * 2 + 5);
  841. }
  842. // public static
  843. TQSize kpSelection::minimumSizeForTextStyle (const kpTextStyle &textStyle)
  844. {
  845. return TQSize (minimumWidthForTextStyle (textStyle),
  846. minimumHeightForTextStyle (textStyle));
  847. }
  848. // public static
  849. int kpSelection::preferredMinimumWidthForTextStyle (const kpTextStyle &textStyle)
  850. {
  851. const int about15CharsWidth =
  852. textStyle.fontMetrics ().width (
  853. TQString::fromLatin1 ("1234567890abcde"));
  854. const int preferredMinWidth =
  855. TQMAX (150,
  856. textBorderSize () * 2 + about15CharsWidth);
  857. return TQMAX (minimumWidthForTextStyle (textStyle),
  858. TQMIN (250, preferredMinWidth));
  859. }
  860. // public static
  861. int kpSelection::preferredMinimumHeightForTextStyle (const kpTextStyle &textStyle)
  862. {
  863. const int preferredMinHeight =
  864. textBorderSize () * 2 + textStyle.fontMetrics ().height ();
  865. return TQMAX (minimumHeightForTextStyle (textStyle),
  866. TQMIN (150, preferredMinHeight));
  867. }
  868. // public static
  869. TQSize kpSelection::preferredMinimumSizeForTextStyle (const kpTextStyle &textStyle)
  870. {
  871. return TQSize (preferredMinimumWidthForTextStyle (textStyle),
  872. preferredMinimumHeightForTextStyle (textStyle));
  873. }
  874. // public
  875. int kpSelection::minimumWidth () const
  876. {
  877. if (isText ())
  878. return minimumWidthForTextStyle (textStyle ());
  879. else
  880. return 1;
  881. }
  882. // public
  883. int kpSelection::minimumHeight () const
  884. {
  885. if (isText ())
  886. return minimumHeightForTextStyle (textStyle ());
  887. else
  888. return 1;
  889. }
  890. // public
  891. TQSize kpSelection::minimumSize () const
  892. {
  893. return TQSize (minimumWidth (), minimumHeight ());
  894. }
  895. // public
  896. int kpSelection::textRowForPoint (const TQPoint &globalPoint) const
  897. {
  898. if (!isText ())
  899. {
  900. kdError () << "kpSelection::textRowForPoint() not a text selection" << endl;
  901. return -1;
  902. }
  903. if (!pointIsInTextArea (globalPoint))
  904. return -1;
  905. const TQFontMetrics fontMetrics (m_textStyle.fontMetrics ());
  906. int row = (globalPoint.y () - textAreaRect ().y ()) /
  907. fontMetrics.lineSpacing ();
  908. if (row >= (int) m_textLines.size ())
  909. row = m_textLines.size () - 1;
  910. return row;
  911. }
  912. // public
  913. int kpSelection::textColForPoint (const TQPoint &globalPoint) const
  914. {
  915. if (!isText ())
  916. {
  917. kdError () << "kpSelection::textColForPoint() not a text selection" << endl;
  918. return -1;
  919. }
  920. int row = textRowForPoint (globalPoint);
  921. if (row < 0 || row >= (int) m_textLines.size ())
  922. return -1;
  923. const int localX = globalPoint.x () - textAreaRect ().x ();
  924. const TQFontMetrics fontMetrics (m_textStyle.fontMetrics ());
  925. // (should be 0 but call just in case)
  926. int charLocalLeft = fontMetrics.width (m_textLines [row], 0);
  927. // OPT: binary search or guess location then move
  928. for (int col = 0; col < (int) m_textLines [row].length (); col++)
  929. {
  930. // OPT: fontMetrics::charWidth() might be faster
  931. const int nextCharLocalLeft = fontMetrics.width (m_textLines [row], col + 1);
  932. if (localX <= (charLocalLeft + nextCharLocalLeft) / 2)
  933. return col;
  934. charLocalLeft = nextCharLocalLeft;
  935. }
  936. return m_textLines [row].length ()/*past end of line*/;
  937. }
  938. // public
  939. TQPoint kpSelection::pointForTextRowCol (int row, int col)
  940. {
  941. if (!isText ())
  942. {
  943. kdError () << "kpSelection::pointForTextRowCol() not a text selection" << endl;
  944. return KP_INVALID_POINT;
  945. }
  946. if (row < 0 || row >= (int) m_textLines.size () ||
  947. col < 0 || col > (int) m_textLines [row].length ())
  948. {
  949. #if DEBUG_KP_SELECTION && 1
  950. kdDebug () << "kpSelection::pointForTextRowCol("
  951. << row << ","
  952. << col << ") out of range"
  953. << " textLines='"
  954. << text ()
  955. << "'"
  956. << endl;
  957. #endif
  958. return KP_INVALID_POINT;
  959. }
  960. const TQFontMetrics fontMetrics (m_textStyle.fontMetrics ());
  961. const int x = fontMetrics.width (m_textLines [row], col);
  962. const int y = row * fontMetrics.height () +
  963. (row >= 1 ? row * fontMetrics.leading () : 0);
  964. return textAreaRect ().topLeft () + TQPoint (x, y);
  965. }
  966. // public
  967. kpTextStyle kpSelection::textStyle () const
  968. {
  969. if (!isText ())
  970. {
  971. kdError () << "kpSelection::textStyle() not a text selection" << endl;
  972. }
  973. return m_textStyle;
  974. }
  975. // public
  976. void kpSelection::setTextStyle (const kpTextStyle &textStyle_)
  977. {
  978. if (!isText ())
  979. {
  980. kdError () << "kpSelection::setTextStyle() not a text selection" << endl;
  981. return;
  982. }
  983. m_textStyle = textStyle_;
  984. calculateTextPixmap ();
  985. emit changed (boundingRect ());
  986. }
  987. // public
  988. TQPixmap kpSelection::opaquePixmap () const
  989. {
  990. TQPixmap *p = pixmap ();
  991. if (p)
  992. {
  993. return *p;
  994. }
  995. else
  996. {
  997. return TQPixmap ();
  998. }
  999. }
  1000. // private
  1001. void kpSelection::calculateTransparencyMask ()
  1002. {
  1003. #if DEBUG_KP_SELECTION
  1004. kdDebug () << "kpSelection::calculateTransparencyMask()" << endl;
  1005. #endif
  1006. if (isText ())
  1007. {
  1008. #if DEBUG_KP_SELECTION
  1009. kdDebug () << "\ttext - no need for transparency mask" << endl;
  1010. #endif
  1011. m_transparencyMask.resize (0, 0);
  1012. return;
  1013. }
  1014. if (!m_pixmap)
  1015. {
  1016. #if DEBUG_KP_SELECTION
  1017. kdDebug () << "\tno pixmap - no need for transparency mask" << endl;
  1018. #endif
  1019. m_transparencyMask.resize (0, 0);
  1020. return;
  1021. }
  1022. if (m_transparency.isOpaque ())
  1023. {
  1024. #if DEBUG_KP_SELECTION
  1025. kdDebug () << "\topaque - no need for transparency mask" << endl;
  1026. #endif
  1027. m_transparencyMask.resize (0, 0);
  1028. return;
  1029. }
  1030. m_transparencyMask.resize (m_pixmap->width (), m_pixmap->height ());
  1031. TQImage image = kpPixmapFX::convertToImage (*m_pixmap);
  1032. TQPainter transparencyMaskPainter (&m_transparencyMask);
  1033. bool hasTransparent = false;
  1034. for (int y = 0; y < m_pixmap->height (); y++)
  1035. {
  1036. for (int x = 0; x < m_pixmap->width (); x++)
  1037. {
  1038. if (kpPixmapFX::getColorAtPixel (image, x, y).isSimilarTo (m_transparency.transparentColor (),
  1039. m_transparency.processedColorSimilarity ()))
  1040. {
  1041. transparencyMaskPainter.setPen (TQt::color1/*make it transparent*/);
  1042. hasTransparent = true;
  1043. }
  1044. else
  1045. {
  1046. transparencyMaskPainter.setPen (TQt::color0/*keep pixel as is*/);
  1047. }
  1048. transparencyMaskPainter.drawPoint (x, y);
  1049. }
  1050. }
  1051. transparencyMaskPainter.end ();
  1052. if (!hasTransparent)
  1053. {
  1054. #if DEBUG_KP_SELECTION
  1055. kdDebug () << "\tcolour useless - completely opaque" << endl;
  1056. #endif
  1057. m_transparencyMask.resize (0, 0);
  1058. return;
  1059. }
  1060. }
  1061. // public
  1062. TQPixmap kpSelection::transparentPixmap () const
  1063. {
  1064. TQPixmap pixmap = opaquePixmap ();
  1065. if (!m_transparencyMask.isNull ())
  1066. {
  1067. kpPixmapFX::paintMaskTransparentWithBrush (&pixmap, TQPoint (0, 0),
  1068. m_transparencyMask);
  1069. }
  1070. return pixmap;
  1071. }
  1072. // public
  1073. kpSelectionTransparency kpSelection::transparency () const
  1074. {
  1075. return m_transparency;
  1076. }
  1077. // public
  1078. bool kpSelection::setTransparency (const kpSelectionTransparency &transparency,
  1079. bool checkTransparentPixmapChanged)
  1080. {
  1081. if (m_transparency == transparency)
  1082. return false;
  1083. m_transparency = transparency;
  1084. bool haveChanged = true;
  1085. TQBitmap oldTransparencyMask = m_transparencyMask;
  1086. calculateTransparencyMask ();
  1087. if (oldTransparencyMask.width () == m_transparencyMask.width () &&
  1088. oldTransparencyMask.height () == m_transparencyMask.height ())
  1089. {
  1090. if (m_transparencyMask.isNull ())
  1091. {
  1092. #if DEBUG_KP_SELECTION
  1093. kdDebug () << "\tboth old and new pixmaps are null - nothing changed" << endl;
  1094. #endif
  1095. haveChanged = false;
  1096. }
  1097. else if (checkTransparentPixmapChanged)
  1098. {
  1099. TQImage oldTransparencyMaskImage = kpPixmapFX::convertToImage (oldTransparencyMask);
  1100. TQImage newTransparencyMaskImage = kpPixmapFX::convertToImage (m_transparencyMask);
  1101. bool changed = false;
  1102. for (int y = 0; y < oldTransparencyMaskImage.height () && !changed; y++)
  1103. {
  1104. for (int x = 0; x < oldTransparencyMaskImage.width () && !changed; x++)
  1105. {
  1106. if (kpPixmapFX::getColorAtPixel (oldTransparencyMaskImage, x, y) !=
  1107. kpPixmapFX::getColorAtPixel (newTransparencyMaskImage, x, y))
  1108. {
  1109. #if DEBUG_KP_SELECTION
  1110. kdDebug () << "\tdiffer at " << TQPoint (x, y)
  1111. << " old=" << (int *) kpPixmapFX::getColorAtPixel (oldTransparencyMaskImage, x, y).toTQRgb ()
  1112. << " new=" << (int *) kpPixmapFX::getColorAtPixel (newTransparencyMaskImage, x, y).toTQRgb ()
  1113. << endl;
  1114. #endif
  1115. changed = true;
  1116. break;
  1117. }
  1118. }
  1119. }
  1120. if (!changed)
  1121. haveChanged = false;
  1122. }
  1123. }
  1124. if (haveChanged)
  1125. emit changed (boundingRect ());
  1126. return haveChanged;
  1127. }
  1128. // private
  1129. void kpSelection::flipPoints (bool horiz, bool vert)
  1130. {
  1131. TQRect oldRect = boundingRect ();
  1132. m_points.translate (-oldRect.x (), -oldRect.y ());
  1133. const TQWMatrix matrix = kpPixmapFX::flipMatrix (oldRect.width (), oldRect.height (),
  1134. horiz, vert);
  1135. m_points = matrix.map (m_points);
  1136. m_points.translate (oldRect.x (), oldRect.y ());
  1137. }
  1138. // public
  1139. void kpSelection::flip (bool horiz, bool vert)
  1140. {
  1141. #if DEBUG_KP_SELECTION && 1
  1142. kdDebug () << "kpSelection::flip(horiz=" << horiz
  1143. << ",vert=" << vert << ")" << endl;
  1144. #endif
  1145. flipPoints (horiz, vert);
  1146. if (m_pixmap)
  1147. {
  1148. #if DEBUG_KP_SELECTION && 1
  1149. kdDebug () << "\thave pixmap - flipping that" << endl;
  1150. #endif
  1151. kpPixmapFX::flip (m_pixmap, horiz, vert);
  1152. }
  1153. if (!m_transparencyMask.isNull ())
  1154. {
  1155. #if DEBUG_KP_SELECTION && 1
  1156. kdDebug () << "\thave transparency mask - flipping that" << endl;
  1157. #endif
  1158. kpPixmapFX::flip (TQT_TQPIXMAP(&m_transparencyMask), horiz, vert);
  1159. }
  1160. emit changed (boundingRect ());
  1161. }
  1162. #include <kpselection.moc>