krita

kis_background.cc

00001 /*
00002  *  Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
00003  *
00004  *  this program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the gnu general public license as published by
00006  *  the free software foundation; either version 2 of the license, or
00007  *  (at your option) any later version.
00008  *
00009  *  this program is distributed in the hope that it will be useful,
00010  *  but without any warranty; without even the implied warranty of
00011  *  merchantability or fitness for a particular purpose.  see the
00012  *  gnu general public license for more details.
00013  *
00014  *  you should have received a copy of the gnu general public license
00015  *  along with this program; if not, write to the free software
00016  *  foundation, inc., 675 mass ave, cambridge, ma 02139, usa.
00017  */
00018 #include "kis_global.h"
00019 #include "kis_background.h"
00020 #include "kis_integer_maths.h"
00021 
00022 KisBackground::KisBackground()
00023     : KShared()
00024 {
00025     m_patternTile = QImage(PATTERN_WIDTH, PATTERN_HEIGHT, 32);
00026     m_patternTile.setAlphaBuffer(false);
00027 
00028     for (int y = 0; y < PATTERN_HEIGHT; y++)
00029     {
00030         for (int x = 0; x < PATTERN_WIDTH; x++)
00031         {
00032             Q_UINT8 v = 128 + 63 * ((x / 16 + y / 16) % 2);
00033             m_patternTile.setPixel(x, y, qRgb(v, v, v));
00034         }
00035     }
00036 }
00037 
00038 KisBackground::~KisBackground()
00039 {
00040 }
00041 
00042 const QImage& KisBackground::patternTile() const
00043 {
00044     return m_patternTile;
00045 }
00046 
00047 void KisBackground::paintBackground(QImage image, int imageLeftX, int imageTopY)
00048 {
00049     int patternLeftX;
00050 
00051     if (imageLeftX >= 0) {
00052         patternLeftX = imageLeftX % PATTERN_WIDTH;
00053     } else {
00054         patternLeftX = (PATTERN_WIDTH - (-imageLeftX % PATTERN_WIDTH)) % PATTERN_WIDTH;
00055     }
00056 
00057     int patternTopY;
00058 
00059     if (imageTopY >= 0) {
00060         patternTopY = imageTopY % PATTERN_HEIGHT;
00061     } else {
00062         patternTopY = (PATTERN_HEIGHT - (-imageTopY % PATTERN_HEIGHT)) % PATTERN_HEIGHT;
00063     }
00064 
00065     int imageWidth = image.width();
00066     int imageHeight = image.height();
00067 
00068     int patternY = patternTopY;
00069 
00070     for (int y = 0; y < imageHeight; y++)
00071     {
00072         QRgb *imagePixelPtr = reinterpret_cast<QRgb *>(image.scanLine(y));
00073         const QRgb *patternScanLine = reinterpret_cast<const QRgb *>(m_patternTile.scanLine(patternY));
00074         int patternX = patternLeftX;
00075 
00076         for (int x = 0; x < imageWidth; x++)
00077         {
00078             QRgb imagePixel = *imagePixelPtr;
00079             Q_UINT8 imagePixelAlpha = qAlpha(imagePixel);
00080 
00081             if (imagePixelAlpha != 255) {
00082 
00083                 QRgb patternPixel = patternScanLine[patternX];
00084                 Q_UINT8 imageRed = UINT8_BLEND(qRed(imagePixel), qRed(patternPixel), imagePixelAlpha);
00085                 Q_UINT8 imageGreen = UINT8_BLEND(qGreen(imagePixel), qGreen(patternPixel), imagePixelAlpha);
00086                 Q_UINT8 imageBlue = UINT8_BLEND(qBlue(imagePixel), qBlue(patternPixel), imagePixelAlpha);
00087 
00088                 *imagePixelPtr = qRgba(imageRed, imageGreen, imageBlue, 255);
00089             }
00090 
00091             ++imagePixelPtr;
00092             ++patternX;
00093 
00094             if (patternX == PATTERN_WIDTH) {
00095                 patternX = 0;
00096             }
00097         }
00098 
00099         ++patternY;
00100 
00101         if (patternY == PATTERN_HEIGHT) {
00102             patternY = 0;
00103         }
00104     }
00105 }
00106 
00107 void KisBackground::paintBackground(QImage img, const QRect& scaledImageRect, const QSize& scaledImageSize, const QSize& imageSize)
00108 {
00109     if (scaledImageRect.isEmpty() || scaledImageSize.isEmpty() || imageSize.isEmpty()) {
00110         return;
00111     }
00112 
00113     Q_ASSERT(img.size() == scaledImageRect.size());
00114 
00115     if (img.size() != scaledImageRect.size()) {
00116         return;
00117     }
00118 
00119     Q_INT32 imageWidth = imageSize.width();
00120     Q_INT32 imageHeight = imageSize.height();
00121 
00122     for (Q_INT32 y = 0; y < scaledImageRect.height(); ++y) {
00123 
00124         Q_INT32 scaledY = scaledImageRect.y() + y;
00125         Q_INT32 srcY = (scaledY * imageHeight) / scaledImageSize.height();
00126         Q_INT32 patternY = srcY % PATTERN_HEIGHT;
00127 
00128         QRgb *imagePixelPtr = reinterpret_cast<QRgb *>(img.scanLine(y));
00129         const QRgb *patternScanLine = reinterpret_cast<const QRgb *>(m_patternTile.scanLine(patternY));
00130 
00131         for (Q_INT32 x = 0; x < scaledImageRect.width(); ++x) {
00132 
00133             QRgb imagePixel = *imagePixelPtr;
00134             Q_UINT8 imagePixelAlpha = qAlpha(imagePixel);
00135 
00136             if (imagePixelAlpha != 255) {
00137 
00138                 Q_INT32 scaledX = scaledImageRect.x() + x;
00139                 Q_INT32 srcX = (scaledX * imageWidth) / scaledImageSize.width();
00140                 Q_INT32 patternX = srcX % PATTERN_WIDTH;
00141 
00142                 QRgb patternPixel = patternScanLine[patternX];
00143                 Q_UINT8 imageRed = UINT8_BLEND(qRed(imagePixel), qRed(patternPixel), imagePixelAlpha);
00144                 Q_UINT8 imageGreen = UINT8_BLEND(qGreen(imagePixel), qGreen(patternPixel), imagePixelAlpha);
00145                 Q_UINT8 imageBlue = UINT8_BLEND(qBlue(imagePixel), qBlue(patternPixel), imagePixelAlpha);
00146 
00147                 *imagePixelPtr = qRgba(imageRed, imageGreen, imageBlue, 255);
00148             }
00149 
00150             ++imagePixelPtr;
00151         }
00152     }
00153 }
00154 
00155 
KDE Home | KDE Accessibility Home | Description of Access Keys