void KDContext::drawLine(KDPoint p1, KDPoint p2, KDColor c) { // Find the largest gap KDPoint left = KDPointZero, right = KDPointZero; if (p2.x() > p1.x()) { left = p1; right = p2; } else { left = p2; right = p1; } KDPoint top = KDPointZero, bottom = KDPointZero; if (p2.y() > p1.y()) { top = p1; bottom = p2; } else { top = p2; bottom = p1; } assert(right.x() >= left.x()); assert(bottom.y() >= top.y()); KDCoordinate deltaX = 2*(right.x() - left.x()); KDCoordinate deltaY = 2*(bottom.y() - top.y()); KDPoint p = KDPointZero, alwaysTranslate = KDPointZero, conditionalTranslate = KDPointZero; KDCoordinate scanLength, error, minusError, plusError; if (deltaX >= deltaY) { p = left; scanLength = right.x() - left.x(); error = right.x() - left.x(); minusError = deltaY; plusError = deltaX; alwaysTranslate = KDPoint(1,0); conditionalTranslate = KDPoint(0, (right.y() >= left.y() ? 1 : -1)); } else { p = top; scanLength = bottom.y() - top.y(); error = bottom.y() - top.y(); minusError = deltaX; plusError = deltaY; alwaysTranslate = KDPoint(0,1); conditionalTranslate = KDPoint((bottom.x() >= top.x() ? 1 : -1), 0); } KDCoordinate scanCounter = 0; while (scanCounter++ < scanLength) { setPixel(p, c); p = p.translatedBy(alwaysTranslate); error = error - minusError; if (error <= 0) { p = p.translatedBy(conditionalTranslate); error = error + plusError; } } }
void KDContext::writeChar(char character, KDPoint p, KDText::FontSize size, KDColor textColor, KDColor backgroundColor, bool transparentBackground) { if (character == '\n' || character == '\t') { return; } char firstCharacter = size == KDText::FontSize::Large ? BITMAP_LargeFont_FIRST_CHARACTER : BITMAP_SmallFont_FIRST_CHARACTER; int characterHeight = size == KDText::FontSize::Large ? BITMAP_LargeFont_CHARACTER_HEIGHT : BITMAP_SmallFont_CHARACTER_HEIGHT; int characterWidth = size == KDText::FontSize::Large ? BITMAP_LargeFont_CHARACTER_WIDTH : BITMAP_SmallFont_CHARACTER_WIDTH; KDColor * characterBuffer = size == KDText::FontSize::Large ? largeCharacterBuffer : smallCharacterBuffer; KDRect absoluteRect = absoluteFillRect(KDRect(p, characterWidth, characterHeight)); if (transparentBackground) { pullRect(absoluteRect, characterBuffer); } KDCoordinate startingI = m_clippingRect.x() - p.translatedBy(m_origin).x(); KDCoordinate startingJ = m_clippingRect.y() - p.translatedBy(m_origin).y(); startingI = startingI < 0 ? 0 : startingI; startingJ = startingJ < 0 ? 0 : startingJ; for (KDCoordinate j=0; j<absoluteRect.height(); j++) { for (KDCoordinate i=0; i<absoluteRect.width(); i++) { KDColor * currentPixelAdress = characterBuffer + i + absoluteRect.width()*j; uint8_t intensity = 0; if (size == KDText::FontSize::Large) { intensity = bitmapLargeFont[(uint8_t)character-(uint8_t)firstCharacter][j + startingJ][i +startingI]; } else { intensity = bitmapSmallFont[(uint8_t)character-(uint8_t)firstCharacter][j + startingJ][i +startingI]; } KDColor backColor = transparentBackground ? *currentPixelAdress : backgroundColor; *currentPixelAdress = KDColor::blend(textColor, backColor, intensity); } } pushRect(absoluteRect, characterBuffer); }
KDPoint KDContext::writeString(const char * text, KDPoint p, KDText::FontSize size, KDColor textColor, KDColor backgroundColor, int maxLength, bool transparentBackground) { KDPoint position = p; int characterWidth = size == KDText::FontSize::Large ? BITMAP_LargeFont_CHARACTER_WIDTH : BITMAP_SmallFont_CHARACTER_WIDTH; int characterHeight = size == KDText::FontSize::Large ? BITMAP_LargeFont_CHARACTER_HEIGHT: BITMAP_SmallFont_CHARACTER_HEIGHT; KDPoint characterSize(characterWidth, 0); const char * end = text+maxLength; while(*text != 0 && text != end) { writeChar(*text, position, size, textColor, backgroundColor, transparentBackground); if (*text == '\n') { position = KDPoint(0, position.y()+characterHeight); } else if (*text == '\t') { position = position.translatedBy(KDPoint(KDText::k_tabCharacterWidth*characterWidth, 0)); } else { position = position.translatedBy(characterSize); } text++; } return position; }