summaryrefslogtreecommitdiff
path: root/src/gmdocument.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-07-29 07:42:30 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-07-29 07:42:30 +0300
commit4deb72ba6ea6c055dff69d74669887f30ea01e54 (patch)
treeea9b9645b38367afabaa66637c15d9a1cd0c3374 /src/gmdocument.c
parentd921021132367076cd2a5f120b3a49db6e29acf7 (diff)
Showing and hiding image content
Diffstat (limited to 'src/gmdocument.c')
-rw-r--r--src/gmdocument.c89
1 files changed, 68 insertions, 21 deletions
diff --git a/src/gmdocument.c b/src/gmdocument.c
index f8998c17..4a3f8e06 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -33,12 +33,16 @@ iDefineTypeConstruction(GmLink)
33iDeclareType(GmImage) 33iDeclareType(GmImage)
34 34
35struct Impl_GmImage { 35struct Impl_GmImage {
36 iInt2 size; 36 iInt2 size;
37 size_t numBytes;
38 iString mime;
39 iGmLinkId linkId;
37 SDL_Texture *texture; 40 SDL_Texture *texture;
38 iGmLinkId linkId;
39}; 41};
40 42
41void init_GmImage(iGmImage *d, const iBlock *data) { 43void init_GmImage(iGmImage *d, const iBlock *data) {
44 init_String(&d->mime);
45 d->numBytes = size_Block(data);
42 uint8_t *imgData = stbi_load_from_memory( 46 uint8_t *imgData = stbi_load_from_memory(
43 constData_Block(data), size_Block(data), &d->size.x, &d->size.y, NULL, 4); 47 constData_Block(data), size_Block(data), &d->size.x, &d->size.y, NULL, 4);
44 if (!imgData) { 48 if (!imgData) {
@@ -60,6 +64,7 @@ void init_GmImage(iGmImage *d, const iBlock *data) {
60 64
61void deinit_GmImage(iGmImage *d) { 65void deinit_GmImage(iGmImage *d) {
62 SDL_DestroyTexture(d->texture); 66 SDL_DestroyTexture(d->texture);
67 deinit_String(&d->mime);
63} 68}
64 69
65iDefineTypeConstructionArgs(GmImage, (const iBlock *data), data) 70iDefineTypeConstructionArgs(GmImage, (const iBlock *data), data)
@@ -379,6 +384,7 @@ static void doLayout_GmDocument_(iGmDocument *d) {
379 if (link->flags & remote_GmLinkFlag) { 384 if (link->flags & remote_GmLinkFlag) {
380 run.visBounds.pos.x -= gap_UI / 2; 385 run.visBounds.pos.x -= gap_UI / 2;
381 } 386 }
387
382 run.color = linkColor_GmDocument(d, run.linkId); 388 run.color = linkColor_GmDocument(d, run.linkId);
383 pushBack_Array(&d->layout, &run); 389 pushBack_Array(&d->layout, &run);
384 } 390 }
@@ -429,18 +435,29 @@ static void doLayout_GmDocument_(iGmDocument *d) {
429 if (type == link_GmLineType) { 435 if (type == link_GmLineType) {
430 const size_t imgIndex = findLinkImage_GmDocument_(d, run.linkId); 436 const size_t imgIndex = findLinkImage_GmDocument_(d, run.linkId);
431 if (imgIndex != iInvalidPos) { 437 if (imgIndex != iInvalidPos) {
438 ((iGmLink *) at_PtrArray(&d->links, run.linkId - 1))->flags |= content_GmLinkFlag;
432 const iGmImage *img = constAt_PtrArray(&d->images, imgIndex); 439 const iGmImage *img = constAt_PtrArray(&d->images, imgIndex);
440 const int margin = 0.5f * lineHeight_Text(paragraph_FontId);
441 pos.y += margin;
433 run.bounds.pos = pos; 442 run.bounds.pos = pos;
434 run.bounds.size.x = d->size.x; 443 run.bounds.size.x = d->size.x;
435 const float aspect = (float) img->size.y / (float) img->size.x; 444 const float aspect = (float) img->size.y / (float) img->size.x;
436 run.bounds.size.y = d->size.x * aspect; 445 run.bounds.size.y = d->size.x * aspect;
437 run.visBounds = run.bounds; /* TODO: limit max height? */ 446 run.visBounds = run.bounds;
447 const iInt2 maxSize = mulf_I2(img->size, get_Window()->pixelRatio);
448 if (width_Rect(run.visBounds) > maxSize.x) {
449 /* Don't scale the image up. */
450 run.visBounds.size.y = run.visBounds.size.y * maxSize.x / width_Rect(run.visBounds);
451 run.visBounds.size.x = img->size.x;
452 run.visBounds.pos.x = run.bounds.size.x / 2 - width_Rect(run.visBounds) / 2;
453 run.bounds.size.y = run.visBounds.size.y;
454 }
438 run.text = iNullRange; 455 run.text = iNullRange;
439 run.font = 0; 456 run.font = 0;
440 run.color = 0; 457 run.color = 0;
441 run.imageId = imgIndex + 1; 458 run.imageId = imgIndex + 1;
442 pushBack_Array(&d->layout, &run); 459 pushBack_Array(&d->layout, &run);
443 pos.y += run.bounds.size.y; 460 pos.y += run.bounds.size.y + margin;
444 } 461 }
445 } 462 }
446 prevType = type; 463 prevType = type;
@@ -559,17 +576,26 @@ void setSource_GmDocument(iGmDocument *d, const iString *source, int width) {
559} 576}
560 577
561void setImage_GmDocument(iGmDocument *d, iGmLinkId linkId, const iString *mime, const iBlock *data) { 578void setImage_GmDocument(iGmDocument *d, iGmLinkId linkId, const iString *mime, const iBlock *data) {
562 /* TODO: check if we know this MIME type */ 579 if (!mime || !data) {
563 /* Load the image. */ { 580 iGmImage *img;
564 iGmImage *img = new_GmImage(data); 581 if (take_PtrArray(&d->images, findLinkImage_GmDocument_(d, linkId), (void **) &img)) {
565 img->linkId = linkId; /* TODO: use a hash? */
566 if (img->texture) {
567 pushBack_PtrArray(&d->images, img);
568 }
569 else {
570 delete_GmImage(img); 582 delete_GmImage(img);
571 } 583 }
572 } 584 }
585 else {
586 /* TODO: check if we know this MIME type */
587 /* Load the image. */ {
588 iGmImage *img = new_GmImage(data);
589 img->linkId = linkId; /* TODO: use a hash? */
590 set_String(&img->mime, mime);
591 if (img->texture) {
592 pushBack_PtrArray(&d->images, img);
593 }
594 else {
595 delete_GmImage(img);
596 }
597 }
598 }
573 doLayout_GmDocument_(d); 599 doLayout_GmDocument_(d);
574} 600}
575 601
@@ -649,25 +675,34 @@ const iGmRun *findRunAtLoc_GmDocument(const iGmDocument *d, const char *textCStr
649 return NULL; 675 return NULL;
650} 676}
651 677
652const iString *linkUrl_GmDocument(const iGmDocument *d, iGmLinkId linkId) { 678static const iGmLink *link_GmDocument_(const iGmDocument *d, iGmLinkId id) {
653 if (linkId > 0 && linkId <= size_PtrArray(&d->links)) { 679 if (id > 0 && id <= size_PtrArray(&d->links)) {
654 const iGmLink *link = constAt_PtrArray(&d->links, linkId - 1); 680 return constAt_PtrArray(&d->links, id - 1);
655 return &link->url;
656 } 681 }
657 return NULL; 682 return NULL;
658} 683}
659 684
685const iString *linkUrl_GmDocument(const iGmDocument *d, iGmLinkId linkId) {
686 const iGmLink *link = link_GmDocument_(d, linkId);
687 return link ? &link->url : NULL;
688}
689
660int linkFlags_GmDocument(const iGmDocument *d, iGmLinkId linkId) { 690int linkFlags_GmDocument(const iGmDocument *d, iGmLinkId linkId) {
661 if (linkId > 0 && linkId <= size_PtrArray(&d->links)) { 691 const iGmLink *link = link_GmDocument_(d, linkId);
662 const iGmLink *link = constAt_PtrArray(&d->links, linkId - 1); 692 return link ? link->flags : 0;
663 return link->flags; 693}
694
695uint16_t linkImage_GmDocument(const iGmDocument *d, iGmLinkId linkId) {
696 size_t index = findLinkImage_GmDocument_(d, linkId);
697 if (index != iInvalidPos) {
698 return index + 1;
664 } 699 }
665 return 0; 700 return 0;
666} 701}
667 702
668enum iColorId linkColor_GmDocument(const iGmDocument *d, iGmLinkId linkId) { 703enum iColorId linkColor_GmDocument(const iGmDocument *d, iGmLinkId linkId) {
669 if (linkId > 0 && linkId <= size_PtrArray(&d->links)) { 704 const iGmLink *link = link_GmDocument_(d, linkId);
670 const iGmLink *link = constAt_PtrArray(&d->links, linkId - 1); 705 if (link) {
671 return link->flags & http_GmLinkFlag 706 return link->flags & http_GmLinkFlag
672 ? orange_ColorId 707 ? orange_ColorId
673 : link->flags & gopher_GmLinkFlag ? blue_ColorId : cyan_ColorId; 708 : link->flags & gopher_GmLinkFlag ? blue_ColorId : cyan_ColorId;
@@ -688,6 +723,18 @@ SDL_Texture *imageTexture_GmDocument(const iGmDocument *d, uint16_t imageId) {
688 return NULL; 723 return NULL;
689} 724}
690 725
726void imageInfo_GmDocument(const iGmDocument *d, uint16_t imageId, iGmImageInfo *info_out) {
727 if (imageId > 0 && imageId <= size_PtrArray(&d->images)) {
728 const iGmImage *img = constAt_PtrArray(&d->images, imageId - 1);
729 info_out->size = img->size;
730 info_out->numBytes = img->numBytes;
731 info_out->mime = cstr_String(&img->mime);
732 }
733 else {
734 iZap(*info_out);
735 }
736}
737
691const iString *title_GmDocument(const iGmDocument *d) { 738const iString *title_GmDocument(const iGmDocument *d) {
692 return &d->title; 739 return &d->title;
693} 740}