1 #include "HalftoneView.h" 2 3 #include <Bitmap.h> 4 #include <StringView.h> 5 6 HalftonePreviewView::HalftonePreviewView( 7 BRect frame, 8 const char* name, 9 uint32 resizeMask, 10 uint32 flags) 11 : BView(frame, name, resizeMask, flags) 12 { 13 } 14 15 void HalftonePreviewView::preview(float gamma, float min, Halftone::DitherType ditherType, bool color) 16 { 17 const color_space kColorSpace = B_RGB32; 18 const float right = Bounds().Width(); 19 const float bottom = Bounds().Height(); 20 BRect rect(0, 0, right, bottom); 21 22 BBitmap testImage(rect, kColorSpace, true); 23 BBitmap preview(rect, kColorSpace); 24 BView view(rect, "", B_FOLLOW_ALL, B_WILL_DRAW); 25 26 // create test image 27 testImage.Lock(); 28 testImage.AddChild(&view); 29 30 // color bars 31 const int height = Bounds().IntegerHeight()+1; 32 const int width = Bounds().IntegerWidth()+1; 33 const int delta = height / 4; 34 const float red_bottom = delta - 1; 35 const float green_bottom = red_bottom + delta; 36 const float blue_bottom = green_bottom + delta; 37 const float gray_bottom = height - 1; 38 39 for (int x = 0; x <= right; x ++) { 40 uchar value = x * 255 / width; 41 42 BPoint from(x, 0); 43 BPoint to(x, red_bottom); 44 // red 45 view.SetHighColor(255, value, value); 46 view.StrokeLine(from, to); 47 // green 48 from.y = to.y+1; 49 to.y = green_bottom; 50 view.SetHighColor(value, 255, value); 51 view.StrokeLine(from, to); 52 // blue 53 from.y = to.y+1; 54 to.y = blue_bottom; 55 view.SetHighColor(value, value, 255); 56 view.StrokeLine(from, to); 57 // gray 58 from.y = to.y+1; 59 to.y = gray_bottom; 60 view.SetHighColor(value, value, value); 61 view.StrokeLine(from, to); 62 } 63 64 view.Sync(); 65 testImage.RemoveChild(&view); 66 testImage.Unlock(); 67 68 // create preview image 69 Halftone halftone(kColorSpace, gamma, min, ditherType); 70 halftone.setBlackValue(Halftone::kLowValueMeansBlack); 71 72 const int widthBytes = (width + 7) / 8; // byte boundary 73 uchar* buffer = new uchar[widthBytes]; 74 75 const uchar* src = (uchar*)testImage.Bits(); 76 uchar* dstRow = (uchar*)preview.Bits(); 77 78 const int numPlanes = color ? 3 : 1; 79 if (color) { 80 halftone.setPlanes(Halftone::kPlaneRGB1); 81 } 82 83 for (int y = 0; y < height; y ++) { 84 for (int plane = 0; plane < numPlanes; plane ++) { 85 // halftone the preview image 86 halftone.dither(buffer, src, 0, y, width); 87 88 // convert the plane(s) to RGB32 89 ColorRGB32Little* dst = (ColorRGB32Little*)dstRow; 90 const uchar* bitmap = buffer; 91 for (int x = 0; x < width; x ++, dst ++) { 92 const int bit = 7 - (x % 8); 93 const bool isSet = (*bitmap & (1 << bit)) != 0; 94 uchar value = isSet ? 255 : 0; 95 96 if (color) { 97 switch (plane) { 98 case 0: dst->red = value; 99 break; 100 case 1: dst->green = value; 101 break; 102 case 2: dst->blue = value; 103 break; 104 } 105 } else { 106 dst->red = dst->green = dst->blue = value; 107 } 108 109 if (bit == 0) { 110 bitmap ++; 111 } 112 } 113 } 114 115 // next row 116 src += testImage.BytesPerRow(); 117 dstRow += preview.BytesPerRow(); 118 } 119 120 delete buffer; 121 122 SetViewBitmap(&preview); 123 Invalidate(); 124 } 125 126 HalftoneView::HalftoneView( 127 BRect frame, 128 const char* name, 129 uint32 resizeMask, 130 uint32 flags) 131 : BView(frame, name, resizeMask, flags) 132 { 133 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 134 135 BRect r(frame); 136 float size, max; 137 138 r.OffsetTo(0, 0); 139 const int height = r.IntegerHeight()+1; 140 const int delta = height / 4; 141 const float red_top = 0; 142 const float green_top = delta; 143 const float blue_top = green_top + delta; 144 const float gray_top = r.bottom - delta; 145 146 const char* kRedLabel = "Red: "; 147 const char* kGreenLabel = "Green: "; 148 const char* kBlueLabel = "Blue: "; 149 const char* kGrayLabel = "Black: "; 150 151 152 BFont font(be_plain_font); 153 font_height fh; 154 font.GetHeight(&fh); 155 156 max = size = font.StringWidth(kRedLabel); 157 r.Set(0, 0, size, fh.ascent + fh.descent); 158 r.OffsetTo(0, red_top); 159 r.right = r.left + size; 160 AddChild(new BStringView(r, "red", kRedLabel)); 161 162 size = font.StringWidth(kGreenLabel); 163 r.Set(0, 0, size, fh.ascent + fh.descent); 164 if (max < size) max = size; 165 r.OffsetTo(0, green_top); 166 r.right = r.left + size; 167 AddChild(new BStringView(r, "green", kGreenLabel)); 168 169 size = font.StringWidth(kBlueLabel); 170 r.Set(0, 0, size, fh.ascent + fh.descent); 171 if (max < size) max = size; 172 r.OffsetTo(0, blue_top); 173 r.right = r.left + size; 174 AddChild(new BStringView(r, "blue", kBlueLabel)); 175 176 size = font.StringWidth(kGrayLabel); 177 r.Set(0, 0, size, fh.ascent + fh.descent); 178 if (max < size) max = size; 179 r.OffsetTo(0, gray_top); 180 r.right = r.left + size; 181 AddChild(new BStringView(r, "gray", kGrayLabel)); 182 183 r = frame; 184 r.OffsetTo(max, 0); 185 r.right -= max; 186 fPreview = new HalftonePreviewView(r, "preview", resizeMask, flags); 187 AddChild(fPreview); 188 } 189 190 void HalftoneView::preview(float gamma, float min, Halftone::DitherType ditherType, bool color) 191 { 192 fPreview->preview(gamma, min, ditherType, color); 193 } 194