Exemplo n.º 1
0
static inline bool setupBackupBmp(GifInfo* info)
{
	GifFileType* fGIF = info->gifFilePtr;
	info->backupPtr = calloc(fGIF->SWidth * fGIF->SHeight, sizeof(argb));
	if (!info->backupPtr)
	{
		info->gifFilePtr->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
		return false;
	}
	argb paintingColor;
	getColorFromTable(fGIF->SBackGroundColor, &paintingColor, fGIF->SColorMap);
	eraseColor(info->backupPtr, fGIF->SWidth, fGIF->SHeight, paintingColor);
	return true;
}
void KMultiTabBarTab::drawButtonStyled(QPainter *paint) {

	QSize sh;
	const int width = 36; // rotated
	const int height = 24;
	if ((m_style==KMultiTabBar::KDEV3) || (isOn()))
		 sh=KMultiTabBarButton::sizeHint();
	else
		sh=QSize(width,height);

	QPixmap pixmap( sh.width(),height); ///,sh.height());
	pixmap.fill(eraseColor());
	QPainter painter(&pixmap);


	QStyle::SFlags st=QStyle::Style_Default;

	st|=QStyle::Style_Enabled;

	if (isOn()) st|=QStyle::Style_On;

	style().drawControl(QStyle::CE_PushButton,&painter,this, QRect(0,0,pixmap.width(),pixmap.height()), colorGroup(),st);
	style().drawControl(QStyle::CE_PushButtonLabel,&painter,this, QRect(0,0,pixmap.width(),pixmap.height()), colorGroup(),st);

	switch (m_position) {
		case KMultiTabBar::Left:
			paint->rotate(-90);
			paint->drawPixmap(1-pixmap.width(),0,pixmap);
			break;
		case KMultiTabBar::Right:
			paint->rotate(90);
			paint->drawPixmap(0,1-pixmap.height(),pixmap);
			break;

		default:
			paint->drawPixmap(0,0,pixmap);
			break;
	}
//	style().drawControl(QStyle::CE_PushButtonLabel,painter,this, QRect(0,0,pixmap.width(),pixmap.height()),
//		colorGroup(),QStyle::Style_Enabled);


}
void OsmAnd::SymbolRasterizer_P::rasterize(
    const std::shared_ptr<const Primitiviser::PrimitivisedArea>& primitivizedArea,
    QList< std::shared_ptr<const RasterizedSymbolsGroup> >& outSymbolsGroups,
    std::function<bool (const std::shared_ptr<const Model::BinaryMapObject>& mapObject)> filter,
    const IQueryController* const controller)
{
    const auto& env = primitivizedArea->mapPresentationEnvironment;

    for (const auto& symbolGroupEntry : rangeOf(constOf(primitivizedArea->symbolsGroups)))
    {
        if (controller && controller->isAborted())
            return;

        const auto& mapObject = symbolGroupEntry.key();
        const auto& symbolsGroup = symbolGroupEntry.value();

        //////////////////////////////////////////////////////////////////////////
        //if ((mapObject->id >> 1) == 189600735u)
        //{
        //    int i = 5;
        //}
        //else
        //    continue;
        //////////////////////////////////////////////////////////////////////////

        // Apply filter, if it's present
        if (filter && !filter(mapObject))
            continue;

        // Create group
        const std::shared_ptr<RasterizedSymbolsGroup> group(new RasterizedSymbolsGroup(mapObject));

        // Total offset allows several symbols to stack into column. Offset specifies center of symbol bitmap.
        // This offset is computed only in case symbol is not on-path and not along-path
        PointI totalOffset;

        for (const auto& symbol : constOf(symbolsGroup->symbols))
        {
            if (controller && controller->isAborted())
                return;

            if (const auto& textSymbol = std::dynamic_pointer_cast<const Primitiviser::TextSymbol>(symbol))
            {
                TextRasterizer::Style style;
                if (!textSymbol->drawOnPath && textSymbol->shieldResourceName.isEmpty())
                    style.wrapWidth = textSymbol->wrapWidth;
                if (!textSymbol->shieldResourceName.isEmpty())
                    env->obtainTextShield(textSymbol->shieldResourceName, style.backgroundBitmap);
                style
                    .setBold(textSymbol->isBold)
                    .setColor(textSymbol->color)
                    .setSize(textSymbol->size);

                if (textSymbol->shadowRadius > 0)
                {
                    style
                        .setHaloColor(textSymbol->shadowColor)
                        .setHaloRadius(textSymbol->shadowRadius + 2 /*px*/);
                    //NOTE: ^^^ This is same as specifying 'x:2' in style, but due to backward compatibility with Android, leave as-is
                }

                float lineSpacing;
                float symbolExtraTopSpace;
                float symbolExtraBottomSpace;
                QVector<SkScalar> glyphsWidth;
                const auto rasterizedText = TextRasterizer::globalInstance().rasterize(
                    textSymbol->value,
                    style,
                    textSymbol->drawOnPath ? &glyphsWidth : nullptr,
                    &symbolExtraTopSpace,
                    &symbolExtraBottomSpace,
                    &lineSpacing);
                if (!rasterizedText)
                    continue;

#if OSMAND_DUMP_SYMBOLS
                {
                    QDir::current().mkpath("text_symbols");
                    std::unique_ptr<SkImageEncoder> encoder(CreatePNGImageEncoder());
                    QString filename;
                    filename.sprintf("%s\\text_symbols\\%p.png", qPrintable(QDir::currentPath()), rasterizedText.get());
                    encoder->encodeFile(qPrintable(filename), *rasterizedText.get(), 100);
                }
#endif // OSMAND_DUMP_SYMBOLS

                if (textSymbol->drawOnPath)
                {
                    if (textSymbol->drawOnPath && textSymbol->verticalOffset > 0)
                    {
                        LogPrintf(LogSeverityLevel::Warning, "Hey, on-path + vertical offset is not supported!");
                        //assert(false);
                    }

                    // Publish new rasterized symbol
                    const std::shared_ptr<RasterizedOnPathSymbol> rasterizedSymbol(new RasterizedOnPathSymbol(group, textSymbol));
                    rasterizedSymbol->bitmap = qMove(rasterizedText);
                    rasterizedSymbol->order = textSymbol->order;
                    rasterizedSymbol->contentType = RasterizedSymbol::ContentType::Text;
                    rasterizedSymbol->content = textSymbol->value;
                    rasterizedSymbol->languageId = textSymbol->languageId;
                    rasterizedSymbol->minDistance = textSymbol->minDistance;
                    rasterizedSymbol->glyphsWidth = glyphsWidth;
                    group->symbols.push_back(qMove(rasterizedSymbol));
                }
                else
                {
                    // Calculate local offset. Since offset specifies center, it's a sum of
                    //  - vertical offset
                    //  - extra top space (which should be in texture, but not rendered, since transparent)
                    //  - height / 2
                    // This calculation is used only if this symbol is not first. Otherwise only following is used:
                    //  - vertical offset
                    PointI localOffset;
                    localOffset.y += textSymbol->verticalOffset;
                    if (!group->symbols.isEmpty() && !textSymbol->drawAlongPath)
                    {
                        localOffset.y += symbolExtraTopSpace;
                        localOffset.y += rasterizedText->height() / 2;
                    }

                    // Increment total offset
                    if (!textSymbol->drawAlongPath)
                        totalOffset += localOffset;

                    // Publish new rasterized symbol
                    const std::shared_ptr<RasterizedSpriteSymbol> rasterizedSymbol(new RasterizedSpriteSymbol(group, textSymbol));
                    rasterizedSymbol->bitmap = rasterizedText;
                    rasterizedSymbol->order = textSymbol->order;
                    rasterizedSymbol->contentType = RasterizedSymbol::ContentType::Text;
                    rasterizedSymbol->content = textSymbol->value;
                    rasterizedSymbol->languageId = textSymbol->languageId;
                    rasterizedSymbol->minDistance = textSymbol->minDistance;
                    rasterizedSymbol->location31 = textSymbol->location31;
                    rasterizedSymbol->offset = textSymbol->drawAlongPath ? localOffset : totalOffset;
                    rasterizedSymbol->drawAlongPath = textSymbol->drawAlongPath;
                    rasterizedSymbol->intersectionSize = PointI(-1, -1);
                    group->symbols.push_back(qMove(std::shared_ptr<const RasterizedSymbol>(rasterizedSymbol)));

                    // Next symbol should also take into account:
                    //  - height / 2
                    //  - extra bottom space (which should be in texture, but not rendered, since transparent)
                    //  - spacing between lines
                    if (!textSymbol->drawAlongPath)
                    {
                        totalOffset.y += rasterizedText->height() / 2;
                        totalOffset.y += symbolExtraBottomSpace;
                        totalOffset.y += qCeil(lineSpacing);
                    }
                }
            }
            else if (const auto& iconSymbol = std::dynamic_pointer_cast<const Primitiviser::IconSymbol>(symbol))
            {
                std::shared_ptr<const SkBitmap> iconBitmap;
                if (!env->obtainMapIcon(iconSymbol->resourceName, iconBitmap) || !iconBitmap)
                    continue;
                std::shared_ptr<const SkBitmap> backgroundBitmap;
                if (!iconSymbol->shieldResourceName.isEmpty())
                    env->obtainIconShield(iconSymbol->shieldResourceName, backgroundBitmap);

                // Compose final image
                std::shared_ptr<const SkBitmap> rasterizedIcon;
                if (!backgroundBitmap)
                    rasterizedIcon = iconBitmap;
                else
                {
                    // Compute composed image size
                    const auto rasterizedIconWidth = qMax(iconBitmap->width(), backgroundBitmap->width());
                    const auto rasterizedIconHeight = qMax(iconBitmap->height(), backgroundBitmap->height());

                    // Create a bitmap that will be hold entire symbol
                    const auto pRasterizedIcon = new SkBitmap();
                    rasterizedIcon.reset(pRasterizedIcon);
                    pRasterizedIcon->setConfig(SkBitmap::kARGB_8888_Config, rasterizedIconWidth, rasterizedIconHeight);
                    pRasterizedIcon->allocPixels();
                    pRasterizedIcon->eraseColor(SK_ColorTRANSPARENT);
                    
                    // Create canvas
                    SkBitmapDevice target(*pRasterizedIcon);
                    SkCanvas canvas(&target);

                    // Draw the background
                    canvas.drawBitmap(*backgroundBitmap,
                        (rasterizedIconWidth - backgroundBitmap->width()) / 2.0f,
                        (rasterizedIconHeight - backgroundBitmap->height()) / 2.0f,
                        nullptr);

                    // Draw the icon
                    canvas.drawBitmap(*iconBitmap,
                        (rasterizedIconWidth - iconBitmap->width()) / 2.0f,
                        (rasterizedIconHeight - iconBitmap->height()) / 2.0f,
                        nullptr);

                    // Flush all operations
                    canvas.flush();
                }

#if OSMAND_DUMP_SYMBOLS
                {
                    QDir::current().mkpath("icon_symbols");
                    std::unique_ptr<SkImageEncoder> encoder(CreatePNGImageEncoder());
                    QString filename;
                    filename.sprintf("%s\\icon_symbols\\%p.png", qPrintable(QDir::currentPath()), rasterizedIcon.get());
                    encoder->encodeFile(qPrintable(filename), *rasterizedIcon, 100);
                }
#endif // OSMAND_DUMP_SYMBOLS

                // Calculate local offset. Since offset specifies center, it's a sum of
                //  - height / 2
                // This calculation is used only if this symbol is not first. Otherwise nothing is used.
                PointI localOffset;
                if (!group->symbols.isEmpty() && !iconSymbol->drawAlongPath)
                    localOffset.y += rasterizedIcon->height() / 2;

                // Increment total offset
                if (!iconSymbol->drawAlongPath)
                    totalOffset += localOffset;

                // Publish new rasterized symbol
                const std::shared_ptr<RasterizedSpriteSymbol> rasterizedSymbol(new RasterizedSpriteSymbol(group, iconSymbol));
                rasterizedSymbol->bitmap = rasterizedIcon;
                rasterizedSymbol->order = iconSymbol->order;
                rasterizedSymbol->contentType = RasterizedSymbol::ContentType::Icon;
                rasterizedSymbol->content = iconSymbol->resourceName;
                rasterizedSymbol->languageId = LanguageId::Invariant;
                rasterizedSymbol->minDistance = PointI();
                rasterizedSymbol->location31 = iconSymbol->location31;
                rasterizedSymbol->offset = iconSymbol->drawAlongPath ? localOffset : totalOffset;
                rasterizedSymbol->drawAlongPath = iconSymbol->drawAlongPath;
                rasterizedSymbol->intersectionSize = PointI(iconSymbol->intersectionSize, iconSymbol->intersectionSize);
                group->symbols.push_back(qMove(std::shared_ptr<const RasterizedSymbol>(rasterizedSymbol)));

                // Next symbol should also take into account:
                //  - height / 2
                if (!iconSymbol->drawAlongPath)
                    totalOffset.y += rasterizedIcon->height() / 2;
            }
        }

        // Add group to output
        outSymbolsGroups.push_back(qMove(group));
    }
}