| 762 | } |
| 763 | |
| 764 | void |
| 765 | DitherPatternInfo::scale_pattern (unsigned int n) |
| 766 | { |
| 767 | // limit scale factor such that the width and height do not get larger than 64 |
| 768 | while (n * m_width > 64 || n * m_height > 64) { |
| 769 | --n; |
| 770 | } |
| 771 | |
| 772 | if (n <= 1) { |
| 773 | return; |
| 774 | } |
| 775 | |
| 776 | std::vector<uint64_t> new_pattern; |
| 777 | new_pattern.resize (n * m_height, (uint64_t) 0); |
| 778 | |
| 779 | for (unsigned int r = 0; r < m_height; ++r) { |
| 780 | |
| 781 | const uint32_t *p = pattern () [r]; |
| 782 | const uint32_t *pb = pattern () [(r + m_height - 1) % m_height]; |
| 783 | const uint32_t *pt = pattern () [(r + 1) % m_height]; |
| 784 | |
| 785 | for (unsigned int l = 0; l < n; ++l) { |
| 786 | |
| 787 | const uint32_t *py1 = (l < n / 2) ? pb : pt; |
| 788 | const uint32_t *py2 = (l < n / 2) ? pt : pb; |
| 789 | |
| 790 | uint64_t d = 0; |
| 791 | uint64_t mm = 1; |
| 792 | uint32_t m = 1; |
| 793 | uint32_t mmax = 1 << m_width; |
| 794 | uint32_t ml = m_width > 1 ? (1 << (m_width - 1)) : 1; |
| 795 | uint32_t mr = m_width > 1 ? 2 : 1; |
| 796 | |
| 797 | for (unsigned int c = 0; c < m_width; ++c) { |
| 798 | for (unsigned int b = 0; b < n; ++b) { |
| 799 | if ((*p & m) != 0) { |
| 800 | d |= mm; |
| 801 | } else { |
| 802 | // Try interpolation. |
| 803 | // In the following cases, the center's pixel lower-right quadrant fill be filled: |
| 804 | // |
| 805 | // (A1) (A2) (A3) |
| 806 | // x 0 0 x 0 0 x 0 1 |
| 807 | // 0 0 1 0 0 1 0 0 1 |
| 808 | // 0 1 x 1 1 x 0 1 x |
| 809 | // |
| 810 | // (B1) (B2) |
| 811 | // 0 1 x 0 0 0 |
| 812 | // 0 0 1 1 0 1 |
| 813 | // 0 1 x x 1 x |
| 814 | // |
| 815 | // For easy implementation, we encode the pattern into a byte k with the following significant bits |
| 816 | // (for lower-right subpixel, mirrored accordingly for the other subpixels) |
| 817 | // |
| 818 | // k bits: |
| 819 | // 0 1 2 |
| 820 | // 3 - 4 |
| 821 | // 5 6 7 |
no test coverage detected