Pixels
Pixels.h
1 /*
2  * Pixels. Graphics library for TFT displays.
3  *
4  * Copyright (C) 2012-2013 Igor Repinetski
5  *
6  * The code is written in C/C++ for Arduino and can be easily ported to any microcontroller by rewritting the low level pin access functions.
7  *
8  * Text output methods of the library rely on Pixelmeister's font data format. See: http://pd4ml.com/pixelmeister
9  *
10  * This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/
11  *
12  * Commercial use of the library is possible for licensees of "Pixelmeister (for industry)" product.
13  *
14  * This library includes some code portions and algoritmic ideas derived from works of
15  * - Andreas Schiffler -- aschiffler at ferzkopp dot net (SDL_gfx Project)
16  * - K. Townsend http://microBuilder.eu (lpc1343codebase Project)
17  */
18 
19 /*
20  * Currently supported platforms:
21  *
22  * 1. Reference platform: Arduino Mega, TFT_PQ 2.4 (ILI9325 controller), ITDB02 MEGA Shield v1.1
23  *
24  * More platforms coming soon
25  */
26 
27 #ifndef PIXELS_BASE_H
28 #define PIXELS_BASE_H
29 
30 // #define DISABLE_ANTIALIASING 1
31 
32 #if defined(__AVR__) || defined(TEENSYDUINO)
33  #include <Arduino.h>
34 
35  #define regtype volatile uint8_t
36  #define regsize uint8_t
37 
38  #define cbi(reg, bitmask) *reg &= ~bitmask
39  #define sbi(reg, bitmask) *reg |= bitmask
40  #define pulse_high(reg, bitmask) sbi(reg, bitmask); cbi(reg, bitmask);
41  #define pulse_low(reg, bitmask) cbi(reg, bitmask); sbi(reg, bitmask);
42 
43 #elif defined(__SAM3X8E__)
44  #include <Arduino.h>
45  #define PROGMEM
46  #define prog_uchar const unsigned char
47  #define pgm_read_byte(x) (*((char *)x))
48  #define pgm_read_word(x) ( ((*((unsigned char *)x + 1)) << 8) + (*((unsigned char *)x)))
49  #define pgm_read_byte_near(x) (*((char *)x))
50  #define pgm_read_byte_far(x) (*((char *)x))
51 // #define pgm_read_word(x) (*((short *)(x & 0xfffffffe)))
52 // #define pgm_read_word_near(x) (*((short *)(x & 0xfffffffe))
53 // #define pgm_read_word_far(x) (*((short *)(x & 0xfffffffe)))
54  #define pgm_read_word_near(x) ( ((*((unsigned char *)x + 1)) << 8) + (*((unsigned char *)x)))
55  #define pgm_read_word_far(x) ( ((*((unsigned char *)x + 1)) << 8) + (*((unsigned char *)x))))
56  #define PSTR(x) x
57 #else
58  #define PROGMEM
59  #define prog_uchar byte
60 
61  #define regtype volatile uint32_t
62  #define regsize uint16_t
63 #endif
64 
65 #define swap(a, b) {int16_t buf = a; a = b; b = buf;}
66 
67 #define BITMASK_FONT 1
68 #define ANTIALIASED_FONT 2
69 #define HEADER_LENGTH 5
70 
71 #define SCROLL_SMOOTH 1
72 #define SCROLL_CLEAN 2
73 
74 #define FILL_TOPDOWN 0
75 #define FILL_LEFTRIGHT 0
76 #define FILL_DOWNTOP 1
77 #define FILL_RIGHTLEFT 2
78 
79 #define ORIGIN_RELATIVE true // origin relative to a current scroll position
80 #define ORIGIN_ABSOLUTE false // origin matches physical device pixel coordinates
81 
82 #define PORTRAIT 0
83 #define LANDSCAPE 1
84 #define PORTRAIT_FLIP 2
85 #define LANDSCAPE_FLIP 3
86 
87 #define ipart(X) ((int16_t)(X))
88 #define round(X) ((uint16_t)(((double)(X))+0.5))
89 #define fpart(X) (((double)(X))-(double)ipart(X))
90 #define rfpart(X) (1.0-fpart(X))
91 
92 extern regtype *registerCS; // chip select
93 extern regsize bitmaskCS;
94 
95 #define chipSelect() cbi(registerCS, bitmaskCS)
96 #define chipDeselect() sbi(registerCS, bitmaskCS)
97 
98 class RGB {
99 public:
100  uint8_t red;
101  uint8_t green;
102  uint8_t blue;
103 
104  RGB(uint8_t r, uint8_t g, uint8_t b);
105  RGB();
106 
107  RGB convert565toRGB(uint16_t color);
108  uint16_t convertRGBto565(RGB color);
109  uint16_t convertTo565();
110 };
111 
112 class PixelsBase {
113 protected:
114  /* device physical dimension in portrait orientation */
115  int16_t deviceWidth;
116  int16_t deviceHeight;
117 
118  /* device logical dimension in current orientation */
119  int16_t width;
120  int16_t height;
121 
122  boolean landscape;
123 
124  uint8_t orientation;
125 
126  boolean relativeOrigin;
127 
128  /* currently selected font */
129  prog_uchar* currentFont;
130 
131  RGB foreground;
132  RGB background;
133 
134  double lineWidth;
135 
136  uint8_t fillDirection;
137  boolean antialiasing;
138 
139  boolean scrollSupported;
140  boolean scrollEnabled;
141 
142  int16_t currentScroll;
143  int16_t flipScroll;
144  boolean scrollCleanMode;
145 
146  void printString(int16_t xx, int16_t yy, String text, boolean clean, int8_t kerning[] = NULL);
147  void drawGlyph(int16_t fontType, boolean clean, int16_t xx, int16_t yy,
148  int16_t height, prog_uchar* data, int16_t ptr, int16_t length);
149 
150  virtual void setRegion(int16_t x1, int16_t y1, int16_t x2, int16_t y2) {};
151  void setCurrentPixel(RGB color);
152  void setCurrentPixel(int16_t color);
153  void fill(int b, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
154  virtual void quickFill(int b, int16_t x1, int16_t y1, int16_t x2, int16_t y2) {};
155  void putColor(int16_t x, int16_t y, boolean steep, double weight);
156  RGB computeColor(RGB, double weight);
157  RGB computeColor(RGB fg, uint8_t opacity);
158 
159  void resetRegion();
160 
161  void hLine(int16_t x1, int16_t y1, int16_t x2);
162  void vLine(int16_t x1, int16_t y1, int16_t y2);
163 
164  virtual void deviceWriteData(uint8_t hi, uint8_t lo) {};
165 
166  virtual void scrollCmd() {};
167 
168  virtual void drawCircleAntialiaced(int16_t x, int16_t y, int16_t radius, boolean bordermode);
169  virtual void drawFatLineAntialiased(int16_t x1, int16_t y1, int16_t x2, int16_t y2);
170  virtual void drawLineAntialiased(int16_t x1, int16_t y1, int16_t x2, int16_t y2);
171  virtual void drawRoundRectangleAntialiased(int16_t x, int16_t y, int16_t width, int16_t height, int16_t rx, int16_t ry, boolean bordermode);
172 
173  int16_t* loadFileBytes(String);
174 
175 public:
181  PixelsBase(uint16_t width, uint16_t height);
185  virtual void init() {};
191  void setOrientation(uint8_t orientation);
197  inline uint8_t getOrientation() {
198  return orientation;
199  }
206  virtual void enableAntialiasing(boolean enable) {
207  antialiasing = false;
208  }
209 
214  inline boolean isAntialiased() {
215  return antialiasing;
216  }
222  inline void enableScroll(boolean enable) {
223  scrollEnabled = enable;
224  }
230  inline boolean canScroll() {
231  return scrollEnabled & scrollSupported;
232  }
238  inline void setLineWidth(double width) {
239  lineWidth = width;
240  }
245  inline double getLineWidth() {
246  return lineWidth;
247  }
252  inline int16_t getWidth() {
253  return width;
254  }
259  inline int16_t getHeight() {
260  return height;
261  }
265  inline void setOriginRelative() {
266  relativeOrigin = true;
267  }
272  inline void setOriginAbsolute() {
273  relativeOrigin = false;
274  }
280  inline boolean isOriginRelative() {
281  return relativeOrigin;
282  }
287  virtual void setFillDirection(uint8_t direction) {};
291  void clear();
299  inline void setBackground(uint8_t r, uint8_t g, uint8_t b) {
300  setBackground(RGB(r, g, b));
301  }
309  inline void setColor(uint8_t r, uint8_t g, uint8_t b) {
310  setColor(RGB(r, g, b));
311  }
317  inline void setBackground(RGB color) {
318  background = color;
319  }
325  inline void setColor(RGB color) {
326  foreground = color;
327  }
332  inline RGB getBackground() {
333  return background;
334  }
339  inline RGB getColor() {
340  return foreground;
341  }
351  RGB getPixel(int16_t x, int16_t y);
359  void drawPixel(int16_t x, int16_t y);
371  void drawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2);
380  void drawCircle(int16_t x, int16_t y, int16_t radius);
398  void drawOval(int16_t x, int16_t y, int16_t width, int16_t height);
414  void drawRectangle(int16_t x, int16_t y, int16_t width, int16_t height);
429  void drawRoundRectangle(int16_t x, int16_t y, int16_t width, int16_t height, int16_t r);
437  void fillCircle(int16_t x, int16_t y, int16_t radius);
449  void fillOval(int16_t x, int16_t y, int16_t width, int16_t height);
468  void fillRectangle(int16_t x, int16_t y, int16_t width, int16_t height);
482  void fillRoundRectangle(int16_t x, int16_t y, int16_t width, int16_t height, int16_t r);
496  int8_t drawBitmap(int16_t x, int16_t y, int16_t width, int16_t height, prog_uint16_t* data);
508  int8_t drawCompressedBitmap(int16_t x, int16_t y, uint8_t* data);
519  void drawIcon(int16_t xx, int16_t yy, prog_uchar data[]);
530  void cleanIcon(int16_t xx, int16_t yy, prog_uchar data[]);
543  int8_t loadBitmap(int16_t x, int16_t y, int16_t width, int16_t height, String path);
547  void scroll(int16_t dy, int16_t x1, int16_t x2, int8_t flags);
557  void scroll(int16_t dy, int8_t flags);
564  int setFont(prog_uchar font[]);
581  void print(int16_t xx, int16_t yy, String text, int8_t kerning[] = NULL);
599  void cleanText(int16_t xx, int16_t yy, String text, int8_t kerning[] = NULL);
604  int16_t getTextLineHeight();
609  int16_t getTextBaseline();
620  int16_t getTextWidth(String text, int8_t kerning[] = NULL);
621 };
622 
623 class BitStream {
624 private:
625  uint8_t* data;
626  size_t size;
627  int32_t bitpos;
628 
629 public:
630  BitStream (uint8_t* src_buffer, size_t byte_size, int8_t offset = 0) {
631  bitpos = offset;
632  data = src_buffer;
633  size = byte_size + (offset>>3);
634  }
635 
636  bool endOfData() {
637  return ((bitpos + 1) >> 3) >= size;
638  }
639 
640  uint8_t testCurrentByte() {
641  uint8_t res = (uint8_t)pgm_read_byte_near(data + (bitpos>>3));
642  return res;
643  }
644 
645  uint8_t readBit() {
646  uint8_t res = (uint8_t)(pgm_read_byte_near(data + (bitpos>>3)) & (uint8_t)( (uint16_t)0x80 >> (bitpos & 7) ));
647  bitpos++;
648  return res;
649  }
650 
651  uint8_t readBits(uint8_t len) {
652 
653  uint16_t end_offset = (bitpos + len - 1)>>3;
654  if ( end_offset >= size ) {
655  return 0;
656  }
657 
658  uint8_t i;
659  uint16_t byte_offset = bitpos >> 3;
660  if (byte_offset == end_offset) {
661  uint16_t x = pgm_read_byte_near(data + byte_offset);
662  i = (uint8_t)(x >> (8 - ((bitpos & 7) + len))) & ((1 << len) - 1);
663  } else {
664  uint16_t x = ((uint16_t)pgm_read_byte_near(data + byte_offset) << 8) + pgm_read_byte_near(data + end_offset);
665  i = (uint8_t)(x >> (16 - ((bitpos & 7) + len))) & ((1 << len) - 1);
666  }
667  bitpos += len;
668  return i;
669  }
670 
671  uint16_t readNumber() {
672  int16_t count;
673 
674  int8_t ctr = 1;
675  int16_t base = 2;
676  do {
677  if ( readBit() == 0 ) {
678  uint8_t bits = readBits(ctr);
679  count = base + bits;
680  break;
681  } else {
682  ctr++;
683  base *= 2;
684  if ( ctr == 7 ) {
685  uint8_t bits = readBits(ctr);
686  count = base + bits;
687  break;
688  }
689  }
690  } while ( true );
691 
692  return (uint16_t)count;
693  }
694 };
695 
696 #endif
void drawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2)
int16_t getTextWidth(String text, int8_t kerning[]=NULL)
void setOrientation(uint8_t orientation)
void drawIcon(int16_t xx, int16_t yy, prog_uchar data[])
void fillRoundRectangle(int16_t x, int16_t y, int16_t width, int16_t height, int16_t r)
int16_t getTextLineHeight()
void setOriginAbsolute()
Definition: Pixels.h:272
void setBackground(RGB color)
Definition: Pixels.h:317
int setFont(prog_uchar font[])
void clear()
void drawPixel(int16_t x, int16_t y)
int8_t drawCompressedBitmap(int16_t x, int16_t y, uint8_t *data)
int8_t loadBitmap(int16_t x, int16_t y, int16_t width, int16_t height, String path)
void setColor(uint8_t r, uint8_t g, uint8_t b)
Definition: Pixels.h:309
int8_t drawBitmap(int16_t x, int16_t y, int16_t width, int16_t height, prog_uint16_t *data)
int16_t getWidth()
Definition: Pixels.h:252
void setLineWidth(double width)
Definition: Pixels.h:238
virtual void enableAntialiasing(boolean enable)
Definition: Pixels.h:206
void drawRoundRectangle(int16_t x, int16_t y, int16_t width, int16_t height, int16_t r)
Definition: Pixels.h:98
void print(int16_t xx, int16_t yy, String text, int8_t kerning[]=NULL)
double getLineWidth()
Definition: Pixels.h:245
int16_t getTextBaseline()
uint8_t getOrientation()
Definition: Pixels.h:197
void drawRectangle(int16_t x, int16_t y, int16_t width, int16_t height)
int16_t getHeight()
Definition: Pixels.h:259
void setBackground(uint8_t r, uint8_t g, uint8_t b)
Definition: Pixels.h:299
boolean isAntialiased()
Definition: Pixels.h:214
void setColor(RGB color)
Definition: Pixels.h:325
void scroll(int16_t dy, int16_t x1, int16_t x2, int8_t flags)
boolean isOriginRelative()
Definition: Pixels.h:280
void cleanText(int16_t xx, int16_t yy, String text, int8_t kerning[]=NULL)
void fillRectangle(int16_t x, int16_t y, int16_t width, int16_t height)
RGB getBackground()
Definition: Pixels.h:332
void enableScroll(boolean enable)
Definition: Pixels.h:222
void drawCircle(int16_t x, int16_t y, int16_t radius)
void cleanIcon(int16_t xx, int16_t yy, prog_uchar data[])
void setOriginRelative()
Definition: Pixels.h:265
void fillCircle(int16_t x, int16_t y, int16_t radius)
virtual void setFillDirection(uint8_t direction)
Definition: Pixels.h:287
boolean canScroll()
Definition: Pixels.h:230
void fillOval(int16_t x, int16_t y, int16_t width, int16_t height)
void drawOval(int16_t x, int16_t y, int16_t width, int16_t height)
virtual void init()
Definition: Pixels.h:185
PixelsBase(uint16_t width, uint16_t height)
RGB getPixel(int16_t x, int16_t y)
RGB getColor()
Definition: Pixels.h:339