summaryrefslogtreecommitdiffstats
path: root/src/imageplugins/border/border.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imageplugins/border/border.cpp')
-rw-r--r--src/imageplugins/border/border.cpp393
1 files changed, 393 insertions, 0 deletions
diff --git a/src/imageplugins/border/border.cpp b/src/imageplugins/border/border.cpp
new file mode 100644
index 00000000..00726f58
--- /dev/null
+++ b/src/imageplugins/border/border.cpp
@@ -0,0 +1,393 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-05-25
+ * Description : border threaded image filter.
+ *
+ * Copyright 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright 2006-2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation;
+ * either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * ============================================================ */
+
+// C++ includes.
+
+#include <cmath>
+#include <cstdlib>
+
+// TQt includes.
+
+#include <tqpoint.h>
+#include <tqregion.h>
+#include <tqpointarray.h>
+
+// Local includes.
+
+#include "dimg.h"
+#include "ddebug.h"
+#include "border.h"
+
+namespace DigikamBorderImagesPlugin
+{
+
+Border::Border(Digikam::DImg *image, TQObject *parent, int orgWidth, int orgHeight,
+ TQString borderPath, int borderType, float borderPercent,
+ Digikam::DColor solidColor,
+ Digikam::DColor niepceBorderColor,
+ Digikam::DColor niepceLineColor,
+ Digikam::DColor bevelUpperLeftColor,
+ Digikam::DColor bevelLowerRightColor,
+ Digikam::DColor decorativeFirstColor,
+ Digikam::DColor decorativeSecondColor)
+ : Digikam::DImgThreadedFilter(image, parent, "Border")
+{
+ m_orgWidth = orgWidth;
+ m_orgHeight = orgHeight;
+ m_orgRatio = (float)m_orgWidth / (float)m_orgHeight;
+ m_borderType = borderType;
+ m_borderPath = borderPath;
+ int size = (image->width() > image->height()) ? image->height() : image->width();
+ m_borderMainWidth = (int)(size * borderPercent);
+ m_border2ndWidth = (int)(size * 0.005);
+
+ // Clamp internal border with to 1 pixel to be visible with small image.
+ if (m_border2ndWidth < 1) m_border2ndWidth = 1;
+
+ m_solidColor = solidColor;
+ m_niepceBorderColor = niepceBorderColor;
+ m_niepceLineColor = niepceLineColor;
+ m_bevelUpperLeftColor = bevelUpperLeftColor;
+ m_bevelLowerRightColor = bevelLowerRightColor;
+ m_decorativeFirstColor = decorativeFirstColor;
+ m_decorativeSecondColor = decorativeSecondColor;
+
+ m_preserveAspectRatio = true;
+
+ initFilter();
+}
+
+Border::Border(Digikam::DImg *orgImage, TQObject *parent, int orgWidth, int orgHeight,
+ TQString borderPath, int borderType,
+ int borderWidth1, int borderWidth2, int borderWidth3, int borderWidth4,
+ Digikam::DColor solidColor,
+ Digikam::DColor niepceBorderColor,
+ Digikam::DColor niepceLineColor,
+ Digikam::DColor bevelUpperLeftColor,
+ Digikam::DColor bevelLowerRightColor,
+ Digikam::DColor decorativeFirstColor,
+ Digikam::DColor decorativeSecondColor)
+ : Digikam::DImgThreadedFilter(orgImage, parent, "Border")
+{
+ m_orgWidth = orgWidth;
+ m_orgHeight = orgHeight;
+
+ m_borderType = borderType;
+ m_borderWidth1 = borderWidth1;
+ m_borderWidth2 = borderWidth2;
+ m_borderWidth3 = borderWidth3;
+ m_borderWidth4 = borderWidth4;
+
+ m_solidColor = solidColor;
+ m_niepceBorderColor = niepceBorderColor;
+ m_niepceLineColor = niepceLineColor;
+ m_bevelUpperLeftColor = bevelUpperLeftColor;
+ m_bevelLowerRightColor = bevelLowerRightColor;
+ m_decorativeFirstColor = decorativeFirstColor;
+ m_decorativeSecondColor = decorativeSecondColor;
+
+ m_borderPath = borderPath;
+
+ m_preserveAspectRatio = false;
+
+ initFilter();
+}
+
+void Border::filterImage(void)
+{
+ switch (m_borderType)
+ {
+ case SolidBorder:
+ if (m_preserveAspectRatio)
+ solid(m_orgImage, m_destImage, m_solidColor, m_borderMainWidth);
+ else
+ solid2(m_orgImage, m_destImage, m_solidColor, m_borderWidth1);
+ break;
+
+ case NiepceBorder:
+ if (m_preserveAspectRatio)
+ niepce(m_orgImage, m_destImage, m_niepceBorderColor, m_borderMainWidth,
+ m_niepceLineColor, m_border2ndWidth);
+ else
+ niepce2(m_orgImage, m_destImage, m_niepceBorderColor, m_borderWidth1,
+ m_niepceLineColor, m_borderWidth4);
+ break;
+
+ case BeveledBorder:
+ if (m_preserveAspectRatio)
+ bevel(m_orgImage, m_destImage, m_bevelUpperLeftColor,
+ m_bevelLowerRightColor, m_borderMainWidth);
+ else
+ bevel2(m_orgImage, m_destImage, m_bevelUpperLeftColor,
+ m_bevelLowerRightColor, m_borderWidth1);
+ break;
+
+ case PineBorder:
+ case WoodBorder:
+ case PaperBorder:
+ case ParqueBorder:
+ case IceBorder:
+ case LeafBorder:
+ case MarbleBorder:
+ case RainBorder:
+ case CratersBorder:
+ case DriedBorder:
+ case PinkBorder:
+ case StoneBorder:
+ case ChalkBorder:
+ case GraniteBorder:
+ case RockBorder:
+ case WallBorder:
+ if (m_preserveAspectRatio)
+ pattern(m_orgImage, m_destImage, m_borderMainWidth,
+ m_decorativeFirstColor, m_decorativeSecondColor,
+ m_border2ndWidth, m_border2ndWidth);
+ else
+ pattern2(m_orgImage, m_destImage, m_borderWidth1,
+ m_decorativeFirstColor, m_decorativeSecondColor,
+ m_borderWidth2, m_borderWidth2);
+ break;
+ }
+}
+
+// -- Methods to preserve aspect ratio of image ------------------------------------------
+
+void Border::solid(Digikam::DImg &src, Digikam::DImg &dest, const Digikam::DColor &fg, int borderWidth)
+{
+ if (m_orgWidth > m_orgHeight)
+ {
+ int height = src.height() + borderWidth*2;
+ dest = Digikam::DImg((int)(height*m_orgRatio), height, src.sixteenBit(), src.hasAlpha());
+ dest.fill(fg);
+ dest.bitBltImage(&src, (dest.width()-src.width())/2, borderWidth);
+ }
+ else
+ {
+ int width = src.width() + borderWidth*2;
+ dest = Digikam::DImg(width, (int)(width/m_orgRatio), src.sixteenBit(), src.hasAlpha());
+ dest.fill(fg);
+ dest.bitBltImage(&src, borderWidth, (dest.height()-src.height())/2);
+ }
+}
+
+void Border::niepce(Digikam::DImg &src, Digikam::DImg &dest, const Digikam::DColor &fg,
+ int borderWidth, const Digikam::DColor &bg, int lineWidth)
+{
+ Digikam::DImg tmp;
+ solid(src, tmp, bg, lineWidth);
+ solid(tmp, dest, fg, borderWidth);
+}
+
+void Border::bevel(Digikam::DImg &src, Digikam::DImg &dest, const Digikam::DColor &topColor,
+ const Digikam::DColor &btmColor, int borderWidth)
+{
+ int width, height;
+
+ if (m_orgWidth > m_orgHeight)
+ {
+ height = src.height() + borderWidth*2;
+ width = (int)(height*m_orgRatio);
+ }
+ else
+ {
+ width = src.width() + borderWidth*2;
+ height = (int)(width/m_orgRatio);
+ }
+
+ dest = Digikam::DImg(width, height, src.sixteenBit(), src.hasAlpha());
+ dest.fill(topColor);
+
+ TQPointArray btTriangle(3);
+ btTriangle.setPoint(0, width, 0);
+ btTriangle.setPoint(1, 0, height);
+ btTriangle.setPoint(2, width, height);
+ TQRegion btRegion(btTriangle);
+
+ for(int x=0 ; x < width ; x++)
+ {
+ for(int y=0 ; y < height ; y++)
+ {
+ if (btRegion.contains(TQPoint(x, y)))
+ dest.setPixelColor(x, y, btmColor);
+ }
+ }
+
+ if (m_orgWidth > m_orgHeight)
+ {
+ dest.bitBltImage(&src, (dest.width()-src.width())/2, borderWidth);
+ }
+ else
+ {
+ dest.bitBltImage(&src, borderWidth, (dest.height()-src.height())/2);
+ }
+}
+
+void Border::pattern(Digikam::DImg &src, Digikam::DImg &dest, int borderWidth,
+ const Digikam::DColor &firstColor, const Digikam::DColor &secondColor,
+ int firstWidth, int secondWidth)
+{
+ // Original image with the first solid border around.
+ Digikam::DImg tmp;
+ solid(src, tmp, firstColor, firstWidth);
+
+ // Border tiled image using pattern with second solid border around.
+ int width, height;
+
+ if (m_orgWidth > m_orgHeight)
+ {
+ height = tmp.height() + borderWidth*2;
+ width = (int)(height*m_orgRatio);
+ }
+ else
+ {
+ width = tmp.width() + borderWidth*2;
+ height = (int)(width/m_orgRatio);
+ }
+
+ Digikam::DImg tmp2(width, height, tmp.sixteenBit(), tmp.hasAlpha());
+ DDebug() << "Border File:" << m_borderPath << endl;
+ Digikam::DImg border(m_borderPath);
+ if ( border.isNull() )
+ return;
+
+ border.convertToDepthOfImage(&tmp2);
+
+ for (int x = 0 ; x < width ; x+=border.width())
+ for (int y = 0 ; y < height ; y+=border.height())
+ tmp2.bitBltImage(&border, x, y);
+
+ solid(tmp2, dest, secondColor, secondWidth);
+
+ // Merge both images to one.
+ if (m_orgWidth > m_orgHeight)
+ {
+ dest.bitBltImage(&tmp, (dest.width()-tmp.width())/2, borderWidth);
+ }
+ else
+ {
+ dest.bitBltImage(&tmp, borderWidth, (dest.height()-tmp.height())/2);
+ }
+}
+
+// -- Methods to not-preserve aspect ratio of image ------------------------------------------
+
+
+void Border::solid2(Digikam::DImg &src, Digikam::DImg &dest, const Digikam::DColor &fg, int borderWidth)
+{
+ dest = Digikam::DImg(src.width() + borderWidth*2, src.height() + borderWidth*2,
+ src.sixteenBit(), src.hasAlpha());
+ dest.fill(fg);
+ dest.bitBltImage(&src, borderWidth, borderWidth);
+}
+
+void Border::niepce2(Digikam::DImg &src, Digikam::DImg &dest, const Digikam::DColor &fg, int borderWidth,
+ const Digikam::DColor &bg, int lineWidth)
+{
+ Digikam::DImg tmp;
+ solid2(src, tmp, bg, lineWidth);
+ solid2(tmp, dest, fg, borderWidth);
+}
+
+void Border::bevel2(Digikam::DImg &src, Digikam::DImg &dest, const Digikam::DColor &topColor,
+ const Digikam::DColor &btmColor, int borderWidth)
+{
+ int x, y;
+ int wc;
+
+ dest = Digikam::DImg(src.width() + borderWidth*2,
+ src.height() + borderWidth*2,
+ src.sixteenBit(), src.hasAlpha());
+
+ // top
+
+ for(y=0, wc = (int)dest.width()-1; y < borderWidth; ++y, --wc)
+ {
+ for(x=0; x < wc; ++x)
+ dest.setPixelColor(x, y, topColor);
+
+ for(;x < (int)dest.width(); ++x)
+ dest.setPixelColor(x, y, btmColor);
+ }
+
+ // left and right
+
+ for(; y < (int)dest.height()-borderWidth; ++y)
+ {
+ for(x=0; x < borderWidth; ++x)
+ dest.setPixelColor(x, y, topColor);
+
+ for(x = (int)dest.width()-1; x > (int)dest.width()-borderWidth-1; --x)
+ dest.setPixelColor(x, y, btmColor);
+ }
+
+ // bottom
+
+ for(wc = borderWidth; y < (int)dest.height(); ++y, --wc)
+ {
+ for(x=0; x < wc; ++x)
+ dest.setPixelColor(x, y, topColor);
+
+ for(; x < (int)dest.width(); ++x)
+ dest.setPixelColor(x, y, btmColor);
+ }
+
+ dest.bitBltImage(&src, borderWidth, borderWidth);
+}
+
+void Border::pattern2(Digikam::DImg &src, Digikam::DImg &dest, int borderWidth,
+ const Digikam::DColor &firstColor, const Digikam::DColor &secondColor,
+ int firstWidth, int secondWidth)
+{
+ // Border tile.
+
+ int w = m_orgWidth + borderWidth*2;
+ int h = m_orgHeight + borderWidth*2;
+
+ DDebug() << "Border File:" << m_borderPath << endl;
+ Digikam::DImg border(m_borderPath);
+ if ( border.isNull() )
+ return;
+
+ Digikam::DImg borderImg(w, h, src.sixteenBit(), src.hasAlpha());
+ border.convertToDepthOfImage(&borderImg);
+
+ for (int x = 0 ; x < w ; x+=border.width())
+ for (int y = 0 ; y < h ; y+=border.height())
+ borderImg.bitBltImage(&border, x, y);
+
+ // First line around the pattern tile.
+ Digikam::DImg tmp = borderImg.smoothScale(src.width() + borderWidth*2,
+ src.height() + borderWidth*2 );
+
+ solid2(tmp, dest, firstColor, firstWidth);
+
+ // Second line around original image.
+ tmp.reset();
+ solid2(src, tmp, secondColor, secondWidth);
+
+ // Copy original image.
+ dest.bitBltImage(&tmp, borderWidth, borderWidth);
+}
+
+} // NameSpace DigikamBorderImagesPlugin