Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: skia/picture/SkPictureRecord.cpp

Issue 113827: Remove the remainder of the skia source code from the Chromium repo.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « skia/picture/SkPictureRecord.h ('k') | skia/ports/SkFontHost_FONTPATH.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #include "SkPictureRecord.h"
2 #include "SkTSearch.h"
3
4 #define MIN_WRITER_SIZE 16384
5 #define HEAP_BLOCK_SIZE 4096
6
7 SkPictureRecord::SkPictureRecord() :
8 fHeap(HEAP_BLOCK_SIZE), fWriter(MIN_WRITER_SIZE) {
9 fBitmapIndex = fMatrixIndex = fPaintIndex = fRegionIndex = 1;
10 #ifdef SK_DEBUG_SIZE
11 fPointBytes = fRectBytes = fTextBytes = 0;
12 fPointWrites = fRectWrites = fTextWrites = 0;
13 #endif
14
15 fRestoreOffsetStack.setReserve(32);
16 fRestoreOffsetStack.push(0);
17
18 fPathHeap = NULL; // lazy allocate
19 }
20
21 SkPictureRecord::~SkPictureRecord() {
22 reset();
23 }
24
25 ///////////////////////////////////////////////////////////////////////////////
26
27 int SkPictureRecord::save(SaveFlags flags) {
28 addDraw(SAVE);
29 addInt(flags);
30
31 fRestoreOffsetStack.push(0);
32
33 validate();
34 return this->INHERITED::save(flags);
35 }
36
37 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint,
38 SaveFlags flags) {
39 addDraw(SAVE_LAYER);
40 addRectPtr(bounds);
41 addPaintPtr(paint);
42 addInt(flags);
43
44 fRestoreOffsetStack.push(0);
45
46 validate();
47 return this->INHERITED::saveLayer(bounds, paint, flags);
48 }
49
50 void SkPictureRecord::restore() {
51
52 // patch up the clip offsets
53 {
54 uint32_t restoreOffset = (uint32_t)fWriter.size();
55 uint32_t offset = fRestoreOffsetStack.top();
56 while (offset) {
57 uint32_t* peek = fWriter.peek32(offset);
58 offset = *peek;
59 *peek = restoreOffset;
60 }
61 fRestoreOffsetStack.pop();
62 }
63
64 addDraw(RESTORE);
65 validate();
66 return this->INHERITED::restore();
67 }
68
69 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) {
70 addDraw(TRANSLATE);
71 addScalar(dx);
72 addScalar(dy);
73 validate();
74 return this->INHERITED::translate(dx, dy);
75 }
76
77 bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) {
78 addDraw(SCALE);
79 addScalar(sx);
80 addScalar(sy);
81 validate();
82 return this->INHERITED::scale(sx, sy);
83 }
84
85 bool SkPictureRecord::rotate(SkScalar degrees) {
86 addDraw(ROTATE);
87 addScalar(degrees);
88 validate();
89 return this->INHERITED::rotate(degrees);
90 }
91
92 bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) {
93 addDraw(SKEW);
94 addScalar(sx);
95 addScalar(sy);
96 validate();
97 return this->INHERITED::skew(sx, sy);
98 }
99
100 bool SkPictureRecord::concat(const SkMatrix& matrix) {
101 validate();
102 addDraw(CONCAT);
103 addMatrix(matrix);
104 validate();
105 return this->INHERITED::concat(matrix);
106 }
107
108 bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op) {
109 addDraw(CLIP_RECT);
110 addRect(rect);
111 addInt(op);
112
113 size_t offset = fWriter.size();
114 addInt(fRestoreOffsetStack.top());
115 fRestoreOffsetStack.top() = offset;
116
117 validate();
118 return this->INHERITED::clipRect(rect, op);
119 }
120
121 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op) {
122 addDraw(CLIP_PATH);
123 addPath(path);
124 addInt(op);
125
126 size_t offset = fWriter.size();
127 addInt(fRestoreOffsetStack.top());
128 fRestoreOffsetStack.top() = offset;
129
130 validate();
131 return this->INHERITED::clipPath(path, op);
132 }
133
134 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) {
135 addDraw(CLIP_REGION);
136 addRegion(region);
137 addInt(op);
138
139 size_t offset = fWriter.size();
140 addInt(fRestoreOffsetStack.top());
141 fRestoreOffsetStack.top() = offset;
142
143 validate();
144 return this->INHERITED::clipRegion(region, op);
145 }
146
147 void SkPictureRecord::drawPaint(const SkPaint& paint) {
148 addDraw(DRAW_PAINT);
149 addPaint(paint);
150 validate();
151 }
152
153 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts [],
154 const SkPaint& paint) {
155 addDraw(DRAW_POINTS);
156 addPaint(paint);
157 addInt(mode);
158 addInt(count);
159 fWriter.writeMul4(pts, count * sizeof(SkPoint));
160 validate();
161 }
162
163 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) {
164 addDraw(DRAW_RECT);
165 addPaint(paint);
166 addRect(rect);
167 validate();
168 }
169
170 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) {
171 addDraw(DRAW_PATH);
172 addPaint(paint);
173 addPath(path);
174 validate();
175 }
176
177 void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
178 const SkPaint* paint = NULL) {
179 addDraw(DRAW_BITMAP);
180 addPaintPtr(paint);
181 addBitmap(bitmap);
182 addScalar(left);
183 addScalar(top);
184 validate();
185 }
186
187 void SkPictureRecord::drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
188 const SkRect& dst, const SkPaint* paint) {
189 addDraw(DRAW_BITMAP_RECT);
190 addPaintPtr(paint);
191 addBitmap(bitmap);
192 addIRectPtr(src); // may be null
193 addRect(dst);
194 validate();
195 }
196
197 void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m atrix,
198 const SkPaint* paint) {
199 addDraw(DRAW_BITMAP_MATRIX);
200 addPaintPtr(paint);
201 addBitmap(bitmap);
202 addMatrix(matrix);
203 validate();
204 }
205
206 void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top,
207 const SkPaint* paint = NULL) {
208 addDraw(DRAW_SPRITE);
209 addPaintPtr(paint);
210 addBitmap(bitmap);
211 addInt(left);
212 addInt(top);
213 validate();
214 }
215
216 void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint,
217 SkScalar baselineY) {
218 SkPaint::FontMetrics metrics;
219 paint.getFontMetrics(&metrics);
220 SkRect bounds;
221 // construct a rect so we can see any adjustments from the paint.
222 // we use 0,1 for left,right, just so the rect isn't empty
223 bounds.set(0, metrics.fTop + baselineY,
224 SK_Scalar1, metrics.fBottom + baselineY);
225 (void)paint.computeFastBounds(bounds, &bounds);
226 // now record the top and bottom
227 addScalar(bounds.fTop);
228 addScalar(bounds.fBottom);
229 }
230
231 void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x,
232 SkScalar y, const SkPaint& paint) {
233 bool fast = paint.canComputeFastBounds();
234
235 addDraw(fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT);
236 addPaint(paint);
237 addText(text, byteLength);
238 addScalar(x);
239 addScalar(y);
240 if (fast) {
241 addFontMetricsTopBottom(paint, y);
242 }
243 validate();
244 }
245
246 void SkPictureRecord::drawPosText(const void* text, size_t byteLength,
247 const SkPoint pos[], const SkPaint& paint) {
248 size_t points = paint.countText(text, byteLength);
249 if (0 == points)
250 return;
251
252 bool canUseDrawH = true;
253 // check if the caller really should have used drawPosTextH()
254 {
255 const SkScalar firstY = pos[0].fY;
256 for (size_t index = 1; index < points; index++) {
257 if (pos[index].fY != firstY) {
258 canUseDrawH = false;
259 break;
260 }
261 }
262 }
263
264 bool fast = canUseDrawH && paint.canComputeFastBounds();
265
266 if (fast) {
267 addDraw(DRAW_POS_TEXT_H_TOP_BOTTOM);
268 } else {
269 addDraw(canUseDrawH ? DRAW_POS_TEXT_H : DRAW_POS_TEXT);
270 }
271 addPaint(paint);
272 addText(text, byteLength);
273 addInt(points);
274
275 #ifdef SK_DEBUG_SIZE
276 size_t start = fWriter.size();
277 #endif
278 if (canUseDrawH) {
279 if (fast) {
280 addFontMetricsTopBottom(paint, pos[0].fY);
281 }
282 addScalar(pos[0].fY);
283 SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar));
284 for (size_t index = 0; index < points; index++)
285 *xptr++ = pos[index].fX;
286 }
287 else {
288 fWriter.writeMul4(pos, points * sizeof(SkPoint));
289 }
290 #ifdef SK_DEBUG_SIZE
291 fPointBytes += fWriter.size() - start;
292 fPointWrites += points;
293 #endif
294 validate();
295 }
296
297 void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength,
298 const SkScalar xpos[], SkScalar constY,
299 const SkPaint& paint) {
300 size_t points = paint.countText(text, byteLength);
301 if (0 == points)
302 return;
303
304 bool fast = paint.canComputeFastBounds();
305
306 addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : DRAW_POS_TEXT_H);
307 addPaint(paint);
308 addText(text, byteLength);
309 addInt(points);
310
311 #ifdef SK_DEBUG_SIZE
312 size_t start = fWriter.size();
313 #endif
314 if (fast) {
315 addFontMetricsTopBottom(paint, constY);
316 }
317 addScalar(constY);
318 fWriter.writeMul4(xpos, points * sizeof(SkScalar));
319 #ifdef SK_DEBUG_SIZE
320 fPointBytes += fWriter.size() - start;
321 fPointWrites += points;
322 #endif
323 validate();
324 }
325
326 void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength,
327 const SkPath& path, const SkMatrix* matrix,
328 const SkPaint& paint) {
329 addDraw(DRAW_TEXT_ON_PATH);
330 addPaint(paint);
331 addText(text, byteLength);
332 addPath(path);
333 addMatrixPtr(matrix);
334 validate();
335 }
336
337 void SkPictureRecord::drawPicture(SkPicture& picture) {
338 addDraw(DRAW_PICTURE);
339 addPicture(picture);
340 validate();
341 }
342
343 void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount,
344 const SkPoint vertices[], const SkPoint texs[],
345 const SkColor colors[], SkXfermode*,
346 const uint16_t indices[], int indexCount,
347 const SkPaint& paint) {
348 uint32_t flags = 0;
349 if (texs) {
350 flags |= DRAW_VERTICES_HAS_TEXS;
351 }
352 if (colors) {
353 flags |= DRAW_VERTICES_HAS_COLORS;
354 }
355 if (indexCount > 0) {
356 flags |= DRAW_VERTICES_HAS_INDICES;
357 }
358
359 addDraw(DRAW_VERTICES);
360 addPaint(paint);
361 addInt(flags);
362 addInt(vmode);
363 addInt(vertexCount);
364 addPoints(vertices, vertexCount);
365 if (flags & DRAW_VERTICES_HAS_TEXS) {
366 addPoints(texs, vertexCount);
367 }
368 if (flags & DRAW_VERTICES_HAS_COLORS) {
369 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor));
370 }
371 if (flags & DRAW_VERTICES_HAS_INDICES) {
372 addInt(indexCount);
373 fWriter.writePad(indices, indexCount * sizeof(uint16_t));
374 }
375 }
376
377 ///////////////////////////////////////////////////////////////////////////////
378
379 void SkPictureRecord::reset() {
380 fPathHeap->safeUnref();
381 fPathHeap = NULL;
382
383 fBitmaps.reset();
384 fMatrices.reset();
385 fPaints.reset();
386 fPictureRefs.unrefAll();
387 fRegions.reset();
388 fWriter.reset();
389 fHeap.reset();
390
391 fRestoreOffsetStack.setCount(1);
392 fRestoreOffsetStack.top() = 0;
393
394 fRCRecorder.reset();
395 fTFRecorder.reset();
396 }
397
398 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) {
399 addInt(find(fBitmaps, bitmap));
400 }
401
402 void SkPictureRecord::addMatrix(const SkMatrix& matrix) {
403 addMatrixPtr(&matrix);
404 }
405
406 void SkPictureRecord::addMatrixPtr(const SkMatrix* matrix) {
407 addInt(find(fMatrices, matrix));
408 }
409
410 void SkPictureRecord::addPaint(const SkPaint& paint) {
411 addPaintPtr(&paint);
412 }
413
414 void SkPictureRecord::addPaintPtr(const SkPaint* paint) {
415 addInt(find(fPaints, paint));
416 }
417
418 void SkPictureRecord::addPath(const SkPath& path) {
419 if (NULL == fPathHeap) {
420 fPathHeap = SkNEW(SkPathHeap);
421 }
422 addInt(fPathHeap->append(path));
423 }
424
425 void SkPictureRecord::addPicture(SkPicture& picture) {
426 int index = fPictureRefs.find(&picture);
427 if (index < 0) { // not found
428 index = fPictureRefs.count();
429 *fPictureRefs.append() = &picture;
430 picture.ref();
431 }
432 // follow the convention of recording a 1-based index
433 addInt(index + 1);
434 }
435
436 void SkPictureRecord::addPoint(const SkPoint& point) {
437 #ifdef SK_DEBUG_SIZE
438 size_t start = fWriter.size();
439 #endif
440 fWriter.writePoint(point);
441 #ifdef SK_DEBUG_SIZE
442 fPointBytes += fWriter.size() - start;
443 fPointWrites++;
444 #endif
445 }
446
447 void SkPictureRecord::addPoints(const SkPoint pts[], int count) {
448 fWriter.writeMul4(pts, count * sizeof(SkPoint));
449 #ifdef SK_DEBUG_SIZE
450 fPointBytes += count * sizeof(SkPoint);
451 fPointWrites++;
452 #endif
453 }
454
455 void SkPictureRecord::addRect(const SkRect& rect) {
456 #ifdef SK_DEBUG_SIZE
457 size_t start = fWriter.size();
458 #endif
459 fWriter.writeRect(rect);
460 #ifdef SK_DEBUG_SIZE
461 fRectBytes += fWriter.size() - start;
462 fRectWrites++;
463 #endif
464 }
465
466 void SkPictureRecord::addRectPtr(const SkRect* rect) {
467 if (fWriter.writeBool(rect != NULL)) {
468 fWriter.writeRect(*rect);
469 }
470 }
471
472 void SkPictureRecord::addIRectPtr(const SkIRect* rect) {
473 if (fWriter.writeBool(rect != NULL)) {
474 *(SkIRect*)fWriter.reserve(sizeof(SkIRect)) = *rect;
475 }
476 }
477
478 void SkPictureRecord::addRegion(const SkRegion& region) {
479 addInt(find(fRegions, region));
480 }
481
482 void SkPictureRecord::addText(const void* text, size_t byteLength) {
483 #ifdef SK_DEBUG_SIZE
484 size_t start = fWriter.size();
485 #endif
486 addInt(byteLength);
487 fWriter.writePad(text, byteLength);
488 #ifdef SK_DEBUG_SIZE
489 fTextBytes += fWriter.size() - start;
490 fTextWrites++;
491 #endif
492 }
493
494 ///////////////////////////////////////////////////////////////////////////////
495
496 int SkPictureRecord::find(SkTDArray<const SkFlatBitmap* >& bitmaps, const SkBitm ap& bitmap) {
497 SkFlatBitmap* flat = SkFlatBitmap::Flatten(&fHeap, bitmap, fBitmapIndex,
498 &fRCRecorder);
499 int index = SkTSearch<SkFlatData>((const SkFlatData**) bitmaps.begin(),
500 bitmaps.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare) ;
501 if (index >= 0) {
502 // SkBitmap bitmap;
503 // flat->unflatten(&bitmap); // balance ref count
504 return bitmaps[index]->index();
505 }
506 index = ~index;
507 *bitmaps.insert(index) = flat;
508 return fBitmapIndex++;
509 }
510
511 int SkPictureRecord::find(SkTDArray<const SkFlatMatrix* >& matrices, const SkMat rix* matrix) {
512 if (matrix == NULL)
513 return 0;
514 SkFlatMatrix* flat = SkFlatMatrix::Flatten(&fHeap, *matrix, fMatrixIndex);
515 int index = SkTSearch<SkFlatData>((const SkFlatData**) matrices.begin(),
516 matrices.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare );
517 if (index >= 0)
518 return matrices[index]->index();
519 index = ~index;
520 *matrices.insert(index) = flat;
521 return fMatrixIndex++;
522 }
523
524 int SkPictureRecord::find(SkTDArray<const SkFlatPaint* >& paints, const SkPaint* paint) {
525 if (paint == NULL) {
526 return 0;
527 }
528
529 SkFlatPaint* flat = SkFlatPaint::Flatten(&fHeap, *paint, fPaintIndex,
530 &fRCRecorder, &fTFRecorder);
531 int index = SkTSearch<SkFlatData>((const SkFlatData**) paints.begin(),
532 paints.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
533 if (index >= 0) {
534 return paints[index]->index();
535 }
536
537 index = ~index;
538 *paints.insert(index) = flat;
539 return fPaintIndex++;
540 }
541
542 int SkPictureRecord::find(SkTDArray<const SkFlatRegion* >& regions, const SkRegi on& region) {
543 SkFlatRegion* flat = SkFlatRegion::Flatten(&fHeap, region, fRegionIndex);
544 int index = SkTSearch<SkFlatData>((const SkFlatData**) regions.begin(),
545 regions.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare) ;
546 if (index >= 0)
547 return regions[index]->index();
548 index = ~index;
549 *regions.insert(index) = flat;
550 return fRegionIndex++;
551 }
552
553 #ifdef SK_DEBUG_DUMP
554 void SkPictureRecord::dumpMatrices() {
555 int count = fMatrices.count();
556 SkMatrix defaultMatrix;
557 defaultMatrix.reset();
558 for (int index = 0; index < count; index++) {
559 const SkFlatMatrix* flatMatrix = fMatrices[index];
560 flatMatrix->dump();
561 }
562 }
563
564 void SkPictureRecord::dumpPaints() {
565 int count = fPaints.count();
566 for (int index = 0; index < count; index++)
567 fPaints[index]->dump();
568 }
569 #endif
570
571 #ifdef SK_DEBUG_SIZE
572 size_t SkPictureRecord::size() const {
573 size_t result = 0;
574 size_t sizeData;
575 bitmaps(&sizeData);
576 result += sizeData;
577 matrices(&sizeData);
578 result += sizeData;
579 paints(&sizeData);
580 result += sizeData;
581 paths(&sizeData);
582 result += sizeData;
583 pictures(&sizeData);
584 result += sizeData;
585 regions(&sizeData);
586 result += sizeData;
587 result += streamlen();
588 return result;
589 }
590
591 int SkPictureRecord::bitmaps(size_t* size) const {
592 size_t result = 0;
593 int count = fBitmaps.count();
594 for (int index = 0; index < count; index++)
595 result += sizeof(fBitmaps[index]) + fBitmaps[index]->size();
596 *size = result;
597 return count;
598 }
599
600 int SkPictureRecord::matrices(size_t* size) const {
601 int count = fMatrices.count();
602 *size = sizeof(fMatrices[0]) * count;
603 return count;
604 }
605
606 int SkPictureRecord::paints(size_t* size) const {
607 size_t result = 0;
608 int count = fPaints.count();
609 for (int index = 0; index < count; index++)
610 result += sizeof(fPaints[index]) + fPaints[index]->size();
611 *size = result;
612 return count;
613 }
614
615 int SkPictureRecord::paths(size_t* size) const {
616 size_t result = 0;
617 int count = fPaths.count();
618 for (int index = 0; index < count; index++)
619 result += sizeof(fPaths[index]) + fPaths[index]->size();
620 *size = result;
621 return count;
622 }
623
624 int SkPictureRecord::regions(size_t* size) const {
625 size_t result = 0;
626 int count = fRegions.count();
627 for (int index = 0; index < count; index++)
628 result += sizeof(fRegions[index]) + fRegions[index]->size();
629 *size = result;
630 return count;
631 }
632
633 size_t SkPictureRecord::streamlen() const {
634 return fWriter.size();
635 }
636 #endif
637
638 #ifdef SK_DEBUG_VALIDATE
639 void SkPictureRecord::validate() const {
640 validateBitmaps();
641 validateMatrices();
642 validatePaints();
643 validatePaths();
644 validatePictures();
645 validateRegions();
646 }
647
648 void SkPictureRecord::validateBitmaps() const {
649 int count = fBitmaps.count();
650 SkASSERT((unsigned) count < 0x1000);
651 for (int index = 0; index < count; index++) {
652 const SkFlatBitmap* bitPtr = fBitmaps[index];
653 SkASSERT(bitPtr);
654 bitPtr->validate();
655 }
656 }
657
658 void SkPictureRecord::validateMatrices() const {
659 int count = fMatrices.count();
660 SkASSERT((unsigned) count < 0x1000);
661 for (int index = 0; index < count; index++) {
662 const SkFlatMatrix* matrix = fMatrices[index];
663 SkASSERT(matrix);
664 matrix->validate();
665 }
666 }
667
668 void SkPictureRecord::validatePaints() const {
669 int count = fPaints.count();
670 SkASSERT((unsigned) count < 0x1000);
671 for (int index = 0; index < count; index++) {
672 const SkFlatPaint* paint = fPaints[index];
673 SkASSERT(paint);
674 // paint->validate();
675 }
676 }
677
678 void SkPictureRecord::validatePaths() const {
679 int count = fPaths.count();
680 SkASSERT((unsigned) count < 0x1000);
681 for (int index = 0; index < count; index++) {
682 const SkFlatPath* path = fPaths[index];
683 SkASSERT(path);
684 path->validate();
685 }
686 }
687
688 void SkPictureRecord::validateRegions() const {
689 int count = fRegions.count();
690 SkASSERT((unsigned) count < 0x1000);
691 for (int index = 0; index < count; index++) {
692 const SkFlatRegion* region = fRegions[index];
693 SkASSERT(region);
694 region->validate();
695 }
696 }
697 #endif
698
OLDNEW
« no previous file with comments | « skia/picture/SkPictureRecord.h ('k') | skia/ports/SkFontHost_FONTPATH.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698