| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkPerlinNoiseShader.h" | 8 #include "SkPerlinNoiseShader.h" |
| 9 #include "SkColorFilter.h" | 9 #include "SkColorFilter.h" |
| 10 #include "SkReadBuffer.h" | 10 #include "SkReadBuffer.h" |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 point.fX += SK_Scalar1; | 465 point.fX += SK_Scalar1; |
| 466 } | 466 } |
| 467 } | 467 } |
| 468 | 468 |
| 469 ///////////////////////////////////////////////////////////////////// | 469 ///////////////////////////////////////////////////////////////////// |
| 470 | 470 |
| 471 #if SK_SUPPORT_GPU | 471 #if SK_SUPPORT_GPU |
| 472 | 472 |
| 473 class GrGLPerlinNoise : public GrGLSLFragmentProcessor { | 473 class GrGLPerlinNoise : public GrGLSLFragmentProcessor { |
| 474 public: | 474 public: |
| 475 GrGLPerlinNoise(const GrProcessor&); | |
| 476 | |
| 477 void emitCode(EmitArgs&) override; | 475 void emitCode(EmitArgs&) override; |
| 478 | 476 |
| 479 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder* b); | 477 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder*); |
| 480 | 478 |
| 481 protected: | 479 protected: |
| 482 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override
; | 480 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override
; |
| 483 | 481 |
| 484 private: | 482 private: |
| 485 | |
| 486 GrGLSLProgramDataManager::UniformHandle fStitchDataUni; | 483 GrGLSLProgramDataManager::UniformHandle fStitchDataUni; |
| 487 SkPerlinNoiseShader::Type fType; | |
| 488 bool fStitchTiles; | |
| 489 int fNumOctaves; | |
| 490 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni; | 484 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni; |
| 491 | 485 |
| 492 typedef GrGLSLFragmentProcessor INHERITED; | 486 typedef GrGLSLFragmentProcessor INHERITED; |
| 493 }; | 487 }; |
| 494 | 488 |
| 495 ///////////////////////////////////////////////////////////////////// | 489 ///////////////////////////////////////////////////////////////////// |
| 496 | 490 |
| 497 class GrPerlinNoiseEffect : public GrFragmentProcessor { | 491 class GrPerlinNoiseEffect : public GrFragmentProcessor { |
| 498 public: | 492 public: |
| 499 static GrFragmentProcessor* Create(SkPerlinNoiseShader::Type type, | 493 static GrFragmentProcessor* Create(SkPerlinNoiseShader::Type type, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 512 const SkPerlinNoiseShader::StitchData& stitchData() const { return fPainting
Data->fStitchDataInit; } | 506 const SkPerlinNoiseShader::StitchData& stitchData() const { return fPainting
Data->fStitchDataInit; } |
| 513 | 507 |
| 514 SkPerlinNoiseShader::Type type() const { return fType; } | 508 SkPerlinNoiseShader::Type type() const { return fType; } |
| 515 bool stitchTiles() const { return fStitchTiles; } | 509 bool stitchTiles() const { return fStitchTiles; } |
| 516 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency
; } | 510 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency
; } |
| 517 int numOctaves() const { return fNumOctaves; } | 511 int numOctaves() const { return fNumOctaves; } |
| 518 const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); } | 512 const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); } |
| 519 | 513 |
| 520 private: | 514 private: |
| 521 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { | 515 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { |
| 522 return new GrGLPerlinNoise(*this); | 516 return new GrGLPerlinNoise; |
| 523 } | 517 } |
| 524 | 518 |
| 525 virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps, | 519 virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps, |
| 526 GrProcessorKeyBuilder* b) const override
{ | 520 GrProcessorKeyBuilder* b) const override
{ |
| 527 GrGLPerlinNoise::GenKey(*this, caps, b); | 521 GrGLPerlinNoise::GenKey(*this, caps, b); |
| 528 } | 522 } |
| 529 | 523 |
| 530 bool onIsEqual(const GrFragmentProcessor& sBase) const override { | 524 bool onIsEqual(const GrFragmentProcessor& sBase) const override { |
| 531 const GrPerlinNoiseEffect& s = sBase.cast<GrPerlinNoiseEffect>(); | 525 const GrPerlinNoiseEffect& s = sBase.cast<GrPerlinNoiseEffect>(); |
| 532 return fType == s.fType && | 526 return fType == s.fType && |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 SkPerlinNoiseShader::CreateFractalNoise(baseFrequencyX, baseFrequencyY,
numOctaves, seed, | 584 SkPerlinNoiseShader::CreateFractalNoise(baseFrequencyX, baseFrequencyY,
numOctaves, seed, |
| 591 stitchTiles ? &tileSize : nullpt
r) : | 585 stitchTiles ? &tileSize : nullpt
r) : |
| 592 SkPerlinNoiseShader::CreateTurbulence(baseFrequencyX, baseFrequencyY, nu
mOctaves, seed, | 586 SkPerlinNoiseShader::CreateTurbulence(baseFrequencyX, baseFrequencyY, nu
mOctaves, seed, |
| 593 stitchTiles ? &tileSize : nullptr))
; | 587 stitchTiles ? &tileSize : nullptr))
; |
| 594 | 588 |
| 595 return shader->asFragmentProcessor(d->fContext, | 589 return shader->asFragmentProcessor(d->fContext, |
| 596 GrTest::TestMatrix(d->fRandom), nullptr, | 590 GrTest::TestMatrix(d->fRandom), nullptr, |
| 597 kNone_SkFilterQuality); | 591 kNone_SkFilterQuality); |
| 598 } | 592 } |
| 599 | 593 |
| 600 GrGLPerlinNoise::GrGLPerlinNoise(const GrProcessor& processor) | 594 void GrGLPerlinNoise::emitCode(EmitArgs& args) { |
| 601 : fType(processor.cast<GrPerlinNoiseEffect>().type()) | 595 const GrPerlinNoiseEffect& pne = args.fFp.cast<GrPerlinNoiseEffect>(); |
| 602 , fStitchTiles(processor.cast<GrPerlinNoiseEffect>().stitchTiles()) | |
| 603 , fNumOctaves(processor.cast<GrPerlinNoiseEffect>().numOctaves()) { | |
| 604 } | |
| 605 | 596 |
| 606 void GrGLPerlinNoise::emitCode(EmitArgs& args) { | |
| 607 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; | 597 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
| 608 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; | 598 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; |
| 609 SkString vCoords = fragBuilder->ensureFSCoords2D(args.fCoords, 0); | 599 SkString vCoords = fragBuilder->ensureFSCoords2D(args.fCoords, 0); |
| 610 | 600 |
| 611 fBaseFrequencyUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragme
nt_Visibility, | 601 fBaseFrequencyUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragme
nt_Visibility, |
| 612 kVec2f_GrSLType, kDefault_GrS
LPrecision, | 602 kVec2f_GrSLType, kDefault_GrS
LPrecision, |
| 613 "baseFrequency"); | 603 "baseFrequency"); |
| 614 const char* baseFrequencyUni = uniformHandler->getUniformCStr(fBaseFrequency
Uni); | 604 const char* baseFrequencyUni = uniformHandler->getUniformCStr(fBaseFrequency
Uni); |
| 615 | 605 |
| 616 const char* stitchDataUni = nullptr; | 606 const char* stitchDataUni = nullptr; |
| 617 if (fStitchTiles) { | 607 if (pne.stitchTiles()) { |
| 618 fStitchDataUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragm
ent_Visibility, | 608 fStitchDataUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragm
ent_Visibility, |
| 619 kVec2f_GrSLType, kDefault_Gr
SLPrecision, | 609 kVec2f_GrSLType, kDefault_Gr
SLPrecision, |
| 620 "stitchData"); | 610 "stitchData"); |
| 621 stitchDataUni = uniformHandler->getUniformCStr(fStitchDataUni); | 611 stitchDataUni = uniformHandler->getUniformCStr(fStitchDataUni); |
| 622 } | 612 } |
| 623 | 613 |
| 624 // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8 | 614 // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8 |
| 625 const char* chanCoordR = "0.125"; | 615 const char* chanCoordR = "0.125"; |
| 626 const char* chanCoordG = "0.375"; | 616 const char* chanCoordG = "0.375"; |
| 627 const char* chanCoordB = "0.625"; | 617 const char* chanCoordB = "0.625"; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 noiseCode.appendf("\tvec4 %s;\n", floorVal); | 650 noiseCode.appendf("\tvec4 %s;\n", floorVal); |
| 661 noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec); | 651 noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec); |
| 662 noiseCode.appendf("\t%s.zw = %s.xy + vec2(1.0);\n", floorVal, floorVal); | 652 noiseCode.appendf("\t%s.zw = %s.xy + vec2(1.0);\n", floorVal, floorVal); |
| 663 noiseCode.appendf("\tvec2 %s = fract(%s);\n", fractVal, noiseVec); | 653 noiseCode.appendf("\tvec2 %s = fract(%s);\n", fractVal, noiseVec); |
| 664 | 654 |
| 665 // smooth curve : t * t * (3 - 2 * t) | 655 // smooth curve : t * t * (3 - 2 * t) |
| 666 noiseCode.appendf("\n\tvec2 %s = %s * %s * (vec2(3.0) - vec2(2.0) * %s);", | 656 noiseCode.appendf("\n\tvec2 %s = %s * %s * (vec2(3.0) - vec2(2.0) * %s);", |
| 667 noiseSmooth, fractVal, fractVal, fractVal); | 657 noiseSmooth, fractVal, fractVal, fractVal); |
| 668 | 658 |
| 669 // Adjust frequencies if we're stitching tiles | 659 // Adjust frequencies if we're stitching tiles |
| 670 if (fStitchTiles) { | 660 if (pne.stitchTiles()) { |
| 671 noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }", | 661 noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }", |
| 672 floorVal, stitchData, floorVal, stitchData); | 662 floorVal, stitchData, floorVal, stitchData); |
| 673 noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }", | 663 noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }", |
| 674 floorVal, stitchData, floorVal, stitchData); | 664 floorVal, stitchData, floorVal, stitchData); |
| 675 noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }", | 665 noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }", |
| 676 floorVal, stitchData, floorVal, stitchData); | 666 floorVal, stitchData, floorVal, stitchData); |
| 677 noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }", | 667 noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }", |
| 678 floorVal, stitchData, floorVal, stitchData); | 668 floorVal, stitchData, floorVal, stitchData); |
| 679 } | 669 } |
| 680 | 670 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); | 759 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); |
| 770 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); | 760 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); |
| 771 } | 761 } |
| 772 | 762 |
| 773 // Compute 'b' as a linear interpolation of 'u' and 'v' | 763 // Compute 'b' as a linear interpolation of 'u' and 'v' |
| 774 noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmoo
th); | 764 noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmoo
th); |
| 775 // Compute the noise as a linear interpolation of 'a' and 'b' | 765 // Compute the noise as a linear interpolation of 'a' and 'b' |
| 776 noiseCode.appendf("\n\treturn mix(%s.x, %s.y, %s.y);\n", ab, ab, noiseSmooth
); | 766 noiseCode.appendf("\n\treturn mix(%s.x, %s.y, %s.y);\n", ab, ab, noiseSmooth
); |
| 777 | 767 |
| 778 SkString noiseFuncName; | 768 SkString noiseFuncName; |
| 779 if (fStitchTiles) { | 769 if (pne.stitchTiles()) { |
| 780 fragBuilder->emitFunction(kFloat_GrSLType, | 770 fragBuilder->emitFunction(kFloat_GrSLType, |
| 781 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStit
chArgs), | 771 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStit
chArgs), |
| 782 gPerlinNoiseStitchArgs, noiseCode.c_str(), &no
iseFuncName); | 772 gPerlinNoiseStitchArgs, noiseCode.c_str(), &no
iseFuncName); |
| 783 } else { | 773 } else { |
| 784 fragBuilder->emitFunction(kFloat_GrSLType, | 774 fragBuilder->emitFunction(kFloat_GrSLType, |
| 785 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs
), | 775 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs
), |
| 786 gPerlinNoiseArgs, noiseCode.c_str(), &noiseFun
cName); | 776 gPerlinNoiseArgs, noiseCode.c_str(), &noiseFun
cName); |
| 787 } | 777 } |
| 788 | 778 |
| 789 // There are rounding errors if the floor operation is not performed here | 779 // There are rounding errors if the floor operation is not performed here |
| 790 fragBuilder->codeAppendf("\n\t\tvec2 %s = floor(%s.xy) * %s;", | 780 fragBuilder->codeAppendf("\n\t\tvec2 %s = floor(%s.xy) * %s;", |
| 791 noiseVec, vCoords.c_str(), baseFrequencyUni); | 781 noiseVec, vCoords.c_str(), baseFrequencyUni); |
| 792 | 782 |
| 793 // Clear the color accumulator | 783 // Clear the color accumulator |
| 794 fragBuilder->codeAppendf("\n\t\t%s = vec4(0.0);", args.fOutputColor); | 784 fragBuilder->codeAppendf("\n\t\t%s = vec4(0.0);", args.fOutputColor); |
| 795 | 785 |
| 796 if (fStitchTiles) { | 786 if (pne.stitchTiles()) { |
| 797 // Set up TurbulenceInitial stitch values. | 787 // Set up TurbulenceInitial stitch values. |
| 798 fragBuilder->codeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUn
i); | 788 fragBuilder->codeAppendf("vec2 %s = %s;", stitchData, stitchDataUni); |
| 799 } | 789 } |
| 800 | 790 |
| 801 fragBuilder->codeAppendf("\n\t\tfloat %s = 1.0;", ratio); | 791 fragBuilder->codeAppendf("float %s = 1.0;", ratio); |
| 802 | 792 |
| 803 // Loop over all octaves | 793 // Loop over all octaves |
| 804 fragBuilder->codeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave)
{", fNumOctaves); | 794 fragBuilder->codeAppendf("for (int octave = 0; octave < %d; ++octave) {", pn
e.numOctaves()); |
| 805 | 795 |
| 806 fragBuilder->codeAppendf("\n\t\t\t%s += ", args.fOutputColor); | 796 fragBuilder->codeAppendf("%s += ", args.fOutputColor); |
| 807 if (fType != SkPerlinNoiseShader::kFractalNoise_Type) { | 797 if (pne.type() != SkPerlinNoiseShader::kFractalNoise_Type) { |
| 808 fragBuilder->codeAppend("abs("); | 798 fragBuilder->codeAppend("abs("); |
| 809 } | 799 } |
| 810 if (fStitchTiles) { | 800 if (pne.stitchTiles()) { |
| 811 fragBuilder->codeAppendf( | 801 fragBuilder->codeAppendf( |
| 812 "vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s)," | 802 "vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s)," |
| 813 "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))", | 803 "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))", |
| 814 noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData, | 804 noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData, |
| 815 noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData, | 805 noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData, |
| 816 noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData, | 806 noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData, |
| 817 noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData); | 807 noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData); |
| 818 } else { | 808 } else { |
| 819 fragBuilder->codeAppendf( | 809 fragBuilder->codeAppendf( |
| 820 "vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s)," | 810 "vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s)," |
| 821 "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))", | 811 "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))", |
| 822 noiseFuncName.c_str(), chanCoordR, noiseVec, | 812 noiseFuncName.c_str(), chanCoordR, noiseVec, |
| 823 noiseFuncName.c_str(), chanCoordG, noiseVec, | 813 noiseFuncName.c_str(), chanCoordG, noiseVec, |
| 824 noiseFuncName.c_str(), chanCoordB, noiseVec, | 814 noiseFuncName.c_str(), chanCoordB, noiseVec, |
| 825 noiseFuncName.c_str(), chanCoordA, noiseVec); | 815 noiseFuncName.c_str(), chanCoordA, noiseVec); |
| 826 } | 816 } |
| 827 if (fType != SkPerlinNoiseShader::kFractalNoise_Type) { | 817 if (pne.type() != SkPerlinNoiseShader::kFractalNoise_Type) { |
| 828 fragBuilder->codeAppendf(")"); // end of "abs(" | 818 fragBuilder->codeAppendf(")"); // end of "abs(" |
| 829 } | 819 } |
| 830 fragBuilder->codeAppendf(" * %s;", ratio); | 820 fragBuilder->codeAppendf(" * %s;", ratio); |
| 831 | 821 |
| 832 fragBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec); | 822 fragBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec); |
| 833 fragBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio); | 823 fragBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio); |
| 834 | 824 |
| 835 if (fStitchTiles) { | 825 if (pne.stitchTiles()) { |
| 836 fragBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData); | 826 fragBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData); |
| 837 } | 827 } |
| 838 fragBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves | 828 fragBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves |
| 839 | 829 |
| 840 if (fType == SkPerlinNoiseShader::kFractalNoise_Type) { | 830 if (pne.type() == SkPerlinNoiseShader::kFractalNoise_Type) { |
| 841 // The value of turbulenceFunctionResult comes from ((turbulenceFunction
Result) + 1) / 2 | 831 // The value of turbulenceFunctionResult comes from ((turbulenceFunction
Result) + 1) / 2 |
| 842 // by fractalNoise and (turbulenceFunctionResult) by turbulence. | 832 // by fractalNoise and (turbulenceFunctionResult) by turbulence. |
| 843 fragBuilder->codeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", | 833 fragBuilder->codeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", |
| 844 args.fOutputColor,args.fOutputColor); | 834 args.fOutputColor,args.fOutputColor); |
| 845 } | 835 } |
| 846 | 836 |
| 847 // Clamp values | 837 // Clamp values |
| 848 fragBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", args.fOutputColo
r, args.fOutputColor); | 838 fragBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", args.fOutputColo
r, args.fOutputColor); |
| 849 | 839 |
| 850 // Pre-multiply the result | 840 // Pre-multiply the result |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 str->append(" seed: "); | 970 str->append(" seed: "); |
| 981 str->appendScalar(fSeed); | 971 str->appendScalar(fSeed); |
| 982 str->append(" stitch tiles: "); | 972 str->append(" stitch tiles: "); |
| 983 str->append(fStitchTiles ? "true " : "false "); | 973 str->append(fStitchTiles ? "true " : "false "); |
| 984 | 974 |
| 985 this->INHERITED::toString(str); | 975 this->INHERITED::toString(str); |
| 986 | 976 |
| 987 str->append(")"); | 977 str->append(")"); |
| 988 } | 978 } |
| 989 #endif | 979 #endif |
| OLD | NEW |