Skip to content

Commit

Permalink
ChafaPlacement: Implement image placements
Browse files Browse the repository at this point in the history
  • Loading branch information
hpjansson committed Dec 31, 2023
1 parent 6384e30 commit c631db0
Show file tree
Hide file tree
Showing 7 changed files with 339 additions and 1 deletion.
2 changes: 2 additions & 0 deletions chafa/Makefile.am
Expand Up @@ -18,6 +18,7 @@ libchafa_la_SOURCES = \
chafa-features.c \
chafa-frame.c \
chafa-image.c \
chafa-placement.c \
chafa-symbol-map.c \
chafa-term-db.c \
chafa-term-info.c \
Expand All @@ -32,6 +33,7 @@ chafainclude_HEADERS = \
chafa-features.h \
chafa-frame.h \
chafa-image.h \
chafa-placement.h \
chafa-symbol-map.h \
chafa-term-db.h \
chafa-term-info.h \
Expand Down
43 changes: 43 additions & 0 deletions chafa/chafa-common.h
Expand Up @@ -68,6 +68,49 @@ typedef enum
}
ChafaPixelType;

/**
* ChafaAlign:
* @CHAFA_ALIGN_START: Align flush with beginning of the area (top or left in LTR locales).
* @CHAFA_ALIGN_END: Align flush with end of the area (bottom or right in LTR locales).
* @CHAFA_ALIGN_CENTER: Align in the middle of the area.
*
* Alignment options when placing an element within an area.
*
* Since: 1.14
**/

typedef enum
{
CHAFA_ALIGN_START,
CHAFA_ALIGN_END,
CHAFA_ALIGN_CENTER,

CHAFA_ALIGN_MAX
}
ChafaAlign;

/**
* ChafaTuck:
* @CHAFA_TUCK_STRETCH: Resize element to fit the area exactly, changing its aspect ratio.
* @CHAFA_TUCK_FIT: Resize element to fit the area, preserving its aspect ratio by adding padding.
* @CHAFA_TUCK_SHRINK_TO_FIT: Like @CHAFA_TUCK_FIT, but prohibit enlargement.
*
* Resizing options when placing an element within an area. Usually used in conjunction
* with #ChafaAlign to control the padding.
*
* Since: 1.14
**/

typedef enum
{
CHAFA_TUCK_STRETCH,
CHAFA_TUCK_FIT,
CHAFA_TUCK_SHRINK_TO_FIT,

CHAFA_TUCK_MAX
}
ChafaTuck;

G_END_DECLS

#endif /* __CHAFA_COMMON_H__ */
4 changes: 3 additions & 1 deletion chafa/chafa-image.c
Expand Up @@ -24,10 +24,12 @@
/**
* SECTION:chafa-image
* @title: ChafaImage
* @short_description: An image that can be placed on a ChafaCanvas
* @short_description: An image to be placed on a #ChafaCanvas
*
* A #ChafaImage represents a raster image for placement on a #ChafaCanvas. It
* can currently hold a single #ChafaFrame.
*
* To place an image on a canvas, it must first be assigned to a #ChafaPlacement.
**/

/**
Expand Down
223 changes: 223 additions & 0 deletions chafa/chafa-placement.c
@@ -0,0 +1,223 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/* Copyright (C) 2018-2023 Hans Petter Jansson
*
* This file is part of Chafa, a program that shows pictures on text terminals.
*
* Chafa is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chafa is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Chafa. If not, see <http://www.gnu.org/licenses/>. */

#include "config.h"
#include "chafa.h"
#include "internal/chafa-private.h"

/**
* SECTION:chafa-placement
* @title: ChafaPlacement
* @short_description: How an image is placed on a #ChafaCanvas
*
* A #ChafaPlacement describes how an image is placed on a #ChafaCanvas. It
* contains information about the image, its alignment and tucking policy.
**/

/**
* chafa_placement_new:
* @image: The image to place on the canvas
* @id: An ID to assign to the placement, or <= 0 to assign one automatically
*
* Creates a new #ChafaPlacement.
*
* Returns: The new placement
*
* Since: 1.14
**/
ChafaPlacement *
chafa_placement_new (ChafaImage *image, gint id)
{
ChafaPlacement *placement;

g_return_val_if_fail (image != NULL, NULL);

if (id < 1)
id = -1;

placement = g_new0 (ChafaPlacement, 1);
placement->refs = 1;

chafa_image_ref (image);
placement->image = image;
placement->id = id;
placement->halign = CHAFA_ALIGN_START;
placement->valign = CHAFA_ALIGN_START;
placement->tuck = CHAFA_TUCK_STRETCH;

return placement;
}

/**
* chafa_placement_ref:
* @placement: Placement to add a reference to
*
* Adds a reference to @placement.
*
* Since: 1.14
**/
void
chafa_placement_ref (ChafaPlacement *placement)
{
gint refs;

g_return_if_fail (placement != NULL);
refs = g_atomic_int_get (&placement->refs);
g_return_if_fail (refs > 0);

g_atomic_int_inc (&placement->refs);
}

/**
* chafa_placement_unref:
* @placement: Placement to remove a reference from
*
* Removes a reference from @placement. When remaining references drops to
* zero, the placement is freed and can no longer be used.
*
* Since: 1.14
**/
void
chafa_placement_unref (ChafaPlacement *placement)
{
gint refs;

g_return_if_fail (placement != NULL);
refs = g_atomic_int_get (&placement->refs);
g_return_if_fail (refs > 0);

if (g_atomic_int_dec_and_test (&placement->refs))
{
g_free (placement);
}
}

/**
* chafa_placement_get_tuck:
* @placement: A #ChafaPlacement
*
* Gets the tucking policy of @placement. This describes how the image is
* resized to fit @placement's extents, and defaults to #CHAFA_TUCK_STRETCH.
*
* Returns: The tucking policy of @placement
*
* Since: 1.14
**/
ChafaTuck
chafa_placement_get_tuck (ChafaPlacement *placement)
{
g_return_val_if_fail (placement != NULL, CHAFA_TUCK_FIT);

return placement->tuck;
}

/**
* chafa_placement_set_tuck:
* @placement: A #ChafaPlacement
* @tuck: Desired tucking policy
*
* Sets the tucking policy for @placement to @tuck. This describes how the image is
* resized to fit @placement's extents, and defaults to #CHAFA_TUCK_STRETCH.
*
* Since: 1.14
**/
void
chafa_placement_set_tuck (ChafaPlacement *placement, ChafaTuck tuck)
{
g_return_if_fail (placement != NULL);

placement->tuck = tuck;
}

/**
* chafa_placement_get_halign:
* @placement: A #ChafaPlacement
*
* Gets the horizontal alignment of @placement. This determines how any
* padding added by the tucking policy is distributed, and defaults to
* #CHAFA_ALIGN_START.
*
* Returns: The horizontal alignment of @placement
*
* Since: 1.14
**/
ChafaAlign
chafa_placement_get_halign (ChafaPlacement *placement)
{
g_return_val_if_fail (placement != NULL, CHAFA_ALIGN_START);

return placement->halign;
}

/**
* chafa_placement_set_halign:
* @placement: A #ChafaPlacement
* @align: Desired horizontal alignment
*
* Sets the horizontal alignment of @placement. This determines how any
* padding added by the tucking policy is distributed, and defaults to
* #CHAFA_ALIGN_START.
*
* Since: 1.14
**/
void
chafa_placement_set_halign (ChafaPlacement *placement, ChafaAlign align)
{
g_return_if_fail (placement != NULL);

placement->halign = align;
}

/**
* chafa_placement_get_valign:
* @placement: A #ChafaPlacement
*
* Gets the vertical alignment of @placement. This determines how any
* padding added by the tucking policy is distributed, and defaults to
* #CHAFA_ALIGN_START.
*
* Returns: The vertical alignment of @placement
*
* Since: 1.14
**/
ChafaAlign
chafa_placement_get_valign (ChafaPlacement *placement)
{
g_return_val_if_fail (placement != NULL, CHAFA_ALIGN_START);

return placement->valign;
}

/**
* chafa_placement_set_valign:
* @placement: A #ChafaPlacement
* @align: Desired vertical alignment
*
* Sets the vertical alignment of @placement. This determines how any
* padding added by the tucking policy is distributed.
*
* Since: 1.14
**/
void
chafa_placement_set_valign (ChafaPlacement *placement, ChafaAlign align)
{
g_return_if_fail (placement != NULL);

placement->valign = align;
}
55 changes: 55 additions & 0 deletions chafa/chafa-placement.h
@@ -0,0 +1,55 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/* Copyright (C) 2018-2023 Hans Petter Jansson
*
* This file is part of Chafa, a program that shows pictures on text terminals.
*
* Chafa is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chafa is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Chafa. If not, see <http://www.gnu.org/licenses/>. */

#ifndef __CHAFA_PLACEMENT_H__
#define __CHAFA_PLACEMENT_H__

#if !defined (__CHAFA_H_INSIDE__) && !defined (CHAFA_COMPILATION)
# error "Only <chafa.h> can be included directly."
#endif

G_BEGIN_DECLS

typedef struct ChafaPlacement ChafaPlacement;

CHAFA_AVAILABLE_IN_1_14
ChafaPlacement *chafa_placement_new (ChafaImage *image, gint id);
CHAFA_AVAILABLE_IN_1_14
void chafa_placement_ref (ChafaPlacement *placement);
CHAFA_AVAILABLE_IN_1_14
void chafa_placement_unref (ChafaPlacement *placement);

CHAFA_AVAILABLE_IN_1_14
ChafaTuck chafa_placement_get_tuck (ChafaPlacement *placement);
CHAFA_AVAILABLE_IN_1_14
void chafa_placement_set_tuck (ChafaPlacement *placement, ChafaTuck tuck);

CHAFA_AVAILABLE_IN_1_14
ChafaAlign chafa_placement_get_halign (ChafaPlacement *placement);
CHAFA_AVAILABLE_IN_1_14
void chafa_placement_set_halign (ChafaPlacement *placement, ChafaAlign align);

CHAFA_AVAILABLE_IN_1_14
ChafaAlign chafa_placement_get_valign (ChafaPlacement *placement);
CHAFA_AVAILABLE_IN_1_14
void chafa_placement_set_valign (ChafaPlacement *placement, ChafaAlign align);

G_END_DECLS

#endif /* __CHAFA_PLACEMENT_H__ */
1 change: 1 addition & 0 deletions chafa/chafa.h
Expand Up @@ -32,6 +32,7 @@ G_BEGIN_DECLS
#include <chafa-features.h>
#include <chafa-frame.h>
#include <chafa-image.h>
#include <chafa-placement.h>
#include <chafa-canvas-config.h>
#include <chafa-canvas.h>
#include <chafa-symbol-map.h>
Expand Down
12 changes: 12 additions & 0 deletions chafa/internal/chafa-private.h
Expand Up @@ -137,6 +137,18 @@ struct ChafaImage
ChafaFrame *frame;
};

/* Placement */

struct ChafaPlacement
{
gint refs;

ChafaImage *image;
gint id;
ChafaAlign halign, valign;
ChafaTuck tuck;
};

/* Canvas */

typedef struct ChafaCanvasCell ChafaCanvasCell;
Expand Down

0 comments on commit c631db0

Please sign in to comment.