Shows a halftone preview.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6579 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* HalftoneView.h
|
||||||
|
* Copyright 2004 Michael Pfeiffer. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _HALFTONE_VIEW_H
|
||||||
|
#define _HALFTONE_VIEW_H
|
||||||
|
|
||||||
|
#include <View.h>
|
||||||
|
#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
|
||||||
|
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
#include "HalftoneView.h"
|
||||||
|
|
||||||
|
#include <Bitmap.h>
|
||||||
|
#include <StringView.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user