From ef6864490578dd5125aaa4ee729e1e6aede9c660 Mon Sep 17 00:00:00 2001 From: Michael Pfeiffer Date: Fri, 13 Feb 2004 23:53:45 +0000 Subject: [PATCH] Shows a halftone preview. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6579 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/print/libprint/HalftoneView.h | 32 +++ .../drivers/shared/libprint/HalftoneView.cpp | 191 ++++++++++++++++++ 2 files changed, 223 insertions(+) create mode 100644 headers/private/print/libprint/HalftoneView.h create mode 100644 src/add-ons/print/drivers/shared/libprint/HalftoneView.cpp diff --git a/headers/private/print/libprint/HalftoneView.h b/headers/private/print/libprint/HalftoneView.h new file mode 100644 index 0000000000..4a2db9a0be --- /dev/null +++ b/headers/private/print/libprint/HalftoneView.h @@ -0,0 +1,32 @@ +/* + * HalftoneView.h + * Copyright 2004 Michael Pfeiffer. All Rights Reserved. + */ + +#ifndef _HALFTONE_VIEW_H +#define _HALFTONE_VIEW_H + +#include +#include "Halftone.h" + +class HalftonePreviewView : public BView +{ +public: + HalftonePreviewView(BRect frame, const char* name, uint32 resizeMask, uint32 flags); + + void preview(float gamma, float min, Halftone::DitherType ditherType, bool color); +}; + +class HalftoneView : public BView +{ +public: + HalftoneView(BRect frame, const char* name, uint32 resizeMask, uint32 flags); + + void preview(float gamma, float min, Halftone::DitherType ditherType, bool color); + +private: + HalftonePreviewView* fPreview; +}; + +#endif + diff --git a/src/add-ons/print/drivers/shared/libprint/HalftoneView.cpp b/src/add-ons/print/drivers/shared/libprint/HalftoneView.cpp new file mode 100644 index 0000000000..8d2dca46c1 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/HalftoneView.cpp @@ -0,0 +1,191 @@ +#include "HalftoneView.h" + +#include +#include + +HalftonePreviewView::HalftonePreviewView( + BRect frame, + const char* name, + uint32 resizeMask, + uint32 flags) + : BView(frame, name, resizeMask, flags) +{ +} + +void HalftonePreviewView::preview(float gamma, float min, Halftone::DitherType ditherType, bool color) +{ + const color_space kColorSpace = B_RGB32; + const float right = Bounds().Width(); + const float bottom = Bounds().Height(); + BRect rect(0, 0, right, bottom); + + BBitmap testImage(rect, kColorSpace, true); + BBitmap preview(rect, kColorSpace); + BView view(rect, "", B_FOLLOW_ALL, B_WILL_DRAW); + + // create test image + testImage.Lock(); + testImage.AddChild(&view); + + // color bars + const int height = Bounds().IntegerHeight()+1; + const int width = Bounds().IntegerWidth()+1; + const int delta = height / 4; + const float red_bottom = delta - 1; + const float green_bottom = red_bottom + delta; + const float blue_bottom = green_bottom + delta; + const float gray_bottom = height - 1; + + for (int x = 0; x <= right; x ++) { + uchar value = x * 255 / width; + + BPoint from(x, 0); + BPoint to(x, red_bottom); + // red + view.SetHighColor(255, value, value); + view.StrokeLine(from, to); + // green + from.y = to.y+1; + to.y = green_bottom; + view.SetHighColor(value, 255, value); + view.StrokeLine(from, to); + // blue + from.y = to.y+1; + to.y = blue_bottom; + view.SetHighColor(value, value, 255); + view.StrokeLine(from, to); + // gray + from.y = to.y+1; + to.y = gray_bottom; + view.SetHighColor(value, value, value); + view.StrokeLine(from, to); + } + + view.Sync(); + testImage.RemoveChild(&view); + testImage.Unlock(); + + // create preview image + Halftone halftone(kColorSpace, gamma, min, ditherType); + halftone.setBlackValue(Halftone::kLowValueMeansBlack); + + const int widthBytes = (width + 7) / 8; // byte boundary + uchar buffer[widthBytes]; + + const uchar* src = (uchar*)testImage.Bits(); + uchar* dstRow = (uchar*)preview.Bits(); + + const int numPlanes = color ? 3 : 1; + if (color) { + halftone.setPlanes(Halftone::kPlaneRGB1); + } + + for (int y = 0; y < height; y ++) { + for (int plane = 0; plane < numPlanes; plane ++) { + // halftone the preview image + halftone.dither(buffer, src, 0, y, width); + + // convert the plane(s) to RGB32 + ColorRGB32Little* dst = (ColorRGB32Little*)dstRow; + const uchar* bitmap = buffer; + for (int x = 0; x < width; x ++, dst ++) { + const int bit = 7 - (x % 8); + const bool isSet = (*bitmap & (1 << bit)) != 0; + uchar value = isSet ? 255 : 0; + + if (color) { + switch (plane) { + case 0: dst->red = value; + break; + case 1: dst->green = value; + break; + case 2: dst->blue = value; + break; + } + } else { + dst->red = dst->green = dst->blue = value; + } + + if (bit == 0) { + bitmap ++; + } + } + } + + // next row + src += testImage.BytesPerRow(); + dstRow += preview.BytesPerRow(); + } + + SetViewBitmap(&preview); + Invalidate(); +} + +HalftoneView::HalftoneView( + BRect frame, + const char* name, + uint32 resizeMask, + uint32 flags) + : BView(frame, name, resizeMask, flags) +{ + SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + BRect r(frame); + float size, max; + + r.OffsetTo(0, 0); + const int height = r.IntegerHeight()+1; + const int delta = height / 4; + const float red_top = 0; + const float green_top = delta; + const float blue_top = green_top + delta; + const float gray_top = r.bottom - delta; + + const char* kRedLabel = "Red: "; + const char* kGreenLabel = "Green: "; + const char* kBlueLabel = "Blue: "; + const char* kGrayLabel = "Black: "; + + + BFont font(be_plain_font); + font_height fh; + font.GetHeight(&fh); + + max = size = font.StringWidth(kRedLabel); + r.Set(0, 0, size, fh.ascent + fh.descent); + r.OffsetTo(0, red_top); + r.right = r.left + size; + AddChild(new BStringView(r, "red", kRedLabel)); + + size = font.StringWidth(kGreenLabel); + r.Set(0, 0, size, fh.ascent + fh.descent); + if (max < size) max = size; + r.OffsetTo(0, green_top); + r.right = r.left + size; + AddChild(new BStringView(r, "green", kGreenLabel)); + + size = font.StringWidth(kBlueLabel); + r.Set(0, 0, size, fh.ascent + fh.descent); + if (max < size) max = size; + r.OffsetTo(0, blue_top); + r.right = r.left + size; + AddChild(new BStringView(r, "blue", kBlueLabel)); + + size = font.StringWidth(kGrayLabel); + r.Set(0, 0, size, fh.ascent + fh.descent); + if (max < size) max = size; + r.OffsetTo(0, gray_top); + r.right = r.left + size; + AddChild(new BStringView(r, "gray", kGrayLabel)); + + r = frame; + r.OffsetTo(max, 0); + r.right -= max; + fPreview = new HalftonePreviewView(r, "preview", resizeMask, flags); + AddChild(fPreview); +} + +void HalftoneView::preview(float gamma, float min, Halftone::DitherType ditherType, bool color) +{ + fPreview->preview(gamma, min, ditherType, color); +}