void OsmAnd::MapRasterizer_P::rasterizePolylineIcons( const Context& context, SkCanvas& canvas, const SkPath& path, const MapStyleEvaluationResult& evalResult) { bool ok; QString pathIconName; ok = evalResult.getStringValue(context.env->styleBuiltinValueDefs->id_OUTPUT_PATH_ICON, pathIconName); if (!ok || pathIconName.isEmpty()) return; float pathIconStep = 0.0f; ok = evalResult.getFloatValue(context.env->styleBuiltinValueDefs->id_OUTPUT_PATH_ICON_STEP, pathIconStep); if (!ok || pathIconStep <= 0.0f) return; std::shared_ptr<const SkBitmap> pathIcon; ok = context.env->obtainMapIcon(pathIconName, pathIcon); if (!ok || !pathIcon) return; SkMatrix mIconTransform; mIconTransform.setIdentity(); mIconTransform.setTranslate(-0.5f * pathIcon->width(), -0.5f * pathIcon->height()); mIconTransform.postRotate(90.0f); SkPathMeasure pathMeasure(path, false); const auto length = pathMeasure.getLength(); auto iconOffset = 0.5f * pathIconStep; const auto iconInstancesCount = static_cast<int>((length - iconOffset) / pathIconStep) + 1; if (iconInstancesCount < 1) return; SkMatrix mIconInstanceTransform; for (auto iconInstanceIdx = 0; iconInstanceIdx < iconInstancesCount; iconInstanceIdx++, iconOffset += pathIconStep) { SkMatrix mPinPoint; ok = pathMeasure.getMatrix(iconOffset, &mPinPoint); if (!ok) break; mIconInstanceTransform.setConcat(mPinPoint, mIconTransform); canvas.save(); canvas.concat(mIconInstanceTransform); canvas.drawBitmap(*pathIcon, 0, 0, &_defaultPaint); canvas.restore(); } }
bool SkDrawPath::getProperty(int index, SkScriptValue* value) const { switch (index) { case SK_PROPERTY(length): if (SkScalarIsNaN(fLength)) { const SkPath& path = ((SkDrawPath*) this)->getPath(); SkPathMeasure pathMeasure(path, false); fLength = pathMeasure.getLength(); } value->fType = SkType_Float; value->fOperand.fScalar = fLength; break; case SK_PROPERTY(fillType): value->fType = SkType_FillType; value->fOperand.fS32 = (int) fPath.getFillType(); break; default: SkASSERT(0); return false; } return true; }